Search code examples
javascriptextjscomboboxextjs4

Ext JS ComboBox: how to fix item at the top of BoundList dropdown


I'm using ComboBoxes to filter products to be displayed on a chart showing sales by month. The stock would look something like this if arranged into a folder structure:

Category: All (3)
|-- Books
|   \-- All (2)
|   \-- Fiction
|       |
|       |-- All (354)
|       |-- Of Mice And Men
|       |-- Infinite Jest
|       |-- (...)
|   \-- Non-fiction
|       |
|       |-- All (17)
|       |-- Surely You're Joking, Mr. Feynman
|       |-- Freakonomics
|       |-- (...)
|
|
|-- Video Games
|   |-- All (2)
|   |-- Strategy
|   \-- Sports
|       |
|       |-- All (3)
|       |-- Soccer
|       |-- Basketball
|       |-- Boxing
|
|
|-- Etc

For each product sub-category I add the value 'All (x)' to the ComboBox's store on the expand event of the ComboBox to make it selectable, where x is the number of items in the sub-category. 'All (x)' is inserted at index 0. The 'All (x)' entry is removed from the ComboBox on collapse.

So far, so good. Problems arise when a user types the beginning of the item they would like to filter the chart by. I cannot find a way to 'sticky' 'All (x)' to the top of the ComboBox so that it does not become sorted as below:

Before typing: https://i.sstatic.net/aM7KX.png

After typing: https://i.sstatic.net/H5gg1.png

I've already tried adding to the change event of the ComboBox to remove and add the 'All (x)' option from the ComboBox's store if it isn't at index 0, but this forces the dropdown to collapse and will not expand without a mouse click on the dropdown arrow. The same goes for adding a listener on the corresponding BoundList refresh event:

{
    extend: 'Ext.form.field.ComboBox',
    queryMode: 'local',
    displayField: 'itemName',
    valueField: 'SKU',
    autoSelect: true,
    typeAhead: true,
    listConfig: {
      listeners: {
        refresh: function(picker) {
            store = picker.getStore();
            // check that the 'All' item is in the store
            if ( store.indexOfId('All') > 0 ) {
                // remove the 'All' entry from the store
                store.remove(store.getById('All'));
                // add it back in
                store.insert(0, {SKU: 'All', itemName: 'All'
                                // etc
                     });
            }
        }
      }
    },

    ...

}

I'd be really grateful if somebody could point me in the right direction to 'sticky' 'All (x)' to the top of the list.


Solution

  • The problem was sortOnFilter defaulting to true. The filterchange event listener was added in Ext JS 4.2.0, and this would have helped a novice like me a great deal in tracking down the problem quickly when stepping through the code.

    NB: I used the Illuminations Firefox browser plugin while troubleshooting and can highly recommend it, even over the Sencha App Inspector plugin for Chrome.