ExtJs combo loses selected value on store page load
Asked Answered
A

3

5

I have an ExtJS 4.1 combo box with a JsonStore and queryMode: 'remote', with paging and filtering, as such:

...
queryMode:      'remote',
allowBlank:     true,
forceSelection: true,
autoSelect:     false,
pageSize:       25,
typeAhead:      true,
minChars:       2,
...

When I load my form with a saved value in this combo box, I load the store passing the saved value as a query (filtering) parameter, to make sure that the selected value is definitely within the returned records, and then I set that value as the combo selected value as such:

    mycombo.getStore().load({
        params: {
            query: displayField
        },
        scope: {
            field: combo,
            valueField: valueField,
            displayField: displayField
        },
        callback: function(records, operation, success) {
            this.field.setValue(this.valueField);
        }
    });

So far, so good, the above works fine. The problem is, that if the user then clicks on the dropdown arrow to select another value for the combo, the 1st page of the store is loaded, erasing all previously selected values, and even if nothing is selected, the previously selected value is lost.

This problem is generic, and is quite similar to this question: ExtJS paged combo with remote JSON store. Display selected value with paging and can be summarized as such:

In an ExtJS combo box with a remote store and paging, selected values are lost when the loaded page changes.

I tried setting clearOnPageLoad: false for the store, but then each time a new page is loaded, the records are appended to the end of the list. I would have expected this parameter to cache the loaded pages and still show me the correct page while moving back and forth.

So, any ideas on how to keep the selected value while moving between pages? I suppose I could create a record with the selected value manually and append it to the store on each page load until a new value is selected, but this sounds like too much effort for something so basic.

Aloeswood answered 7/1, 2013 at 17:11 Comment(0)
A
8

We ended up contacting Sencha support since we have a paid license. This is the answer we got back:


Ext.override(Ext.form.field.ComboBox, {
    onLoad: function() {
        var me = this,
            value = me.value;

        if (me.ignoreSelection > 0) {
            --me.ignoreSelection;
        }

        if (me.rawQuery) {
            me.rawQuery = false;
            me.syncSelection();
            if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
                me.doAutoSelect();
            }
        }

        else {

            if (me.value || me.value === 0) {
                if (me.pageSize === 0) { // added for paging; do not execute on page change
                    me.setValue(me.value);
                }
            } else {


                if (me.store.getCount()) {
                    me.doAutoSelect();
                } else {

                    me.setValue(me.value);
                }
            }
        }
    }
});
Aloeswood answered 1/2, 2013 at 9:40 Comment(2)
It seems that a limitation of this implementation is that the value/display fields are the same. In my application, they are different (i.e., id and name). I think it will be necessary to extend the combo box's interface to set selected value and display.Permeance
It's been a long time since I posted this and I cannot be sure anymore since I'm also not working on that application now, but I don't think that the display and field values were the same. In most practical cases they're not.Aloeswood
R
2

Had the same problem, and 'pruneRemoved: false' didn't work (it seems to be used only in grids). This is the solution:

Ext.override(Ext.form.field.ComboBox,{

    // lastSelection is searched for records
    // (together with store's records which are searched in the parent call)

    findRecord: function(field, value) {
        var foundRec = null;
        Ext.each(this.lastSelection, function(rec) {
            if (rec.get(field) === value) {
                foundRec = rec;
                return false; // stop 'each' loop
            }
        });
        if (foundRec) {
            return foundRec;
        } else {
            return this.callParent(arguments);
        }
    }
});

Hope it doesn't have negative side effects. I've tested it a bit and it seems OK.

Riata answered 24/1, 2013 at 18:9 Comment(1)
Hi, not sure if your solution will work, but I posted the official answer from Sencha support below.Aloeswood
R
0

I am experiencing this issue in extjs 6.0.1.

I discovered a work around that might be helpful for others.

I used override for onLoad to add the selected record from the combo to the store prior to calling the base onLoad.

This works because if the selected record is in the page being viewed, the combo is smart enough to not clear the selection. In other words, the reason the selection is being cleared as you page is because the selected record is not in the page you are viewing.

onLoad: function (store, records, success)
{
    var selection = this.getSelection();

    if (selection)
    {
        records.unshift(selection);
        store.insert(0, records);
    }

    this.callParent(arguments);
}
Rattle answered 21/4, 2016 at 20:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.