Search code examples
formsextjsdata-bindingcomboboxextjs7

ExtJS 7.2 - Loading record into a form with chained comboboxes and forceSelection:true does not load all values


I have a form with two chained comboboxes. The first chained combobox dictates the values that appear in the second. I have forceSelection:true on the second combobox so that when a user changes the first combo, the second will be set blank because it no longer will be a valid option. The chained combos function as expected but when I load a record into this form using getForm().loadRecord(record) the value for the first combo is set properly but the second is not unless I set forceSelection:false.

The following fiddle should make things pretty clear: sencha fiddle

Clicking "Load Record" should load in Fruits/Apple, but only Fruits is shown. Clicking "Load Record" a second time achieves the desired result. If you comment out forceSelection: true it works as expected but then the chained combos don't function as desired. Is there anything I'm doing wrong here?


Solution

  • It is not so easy. What is happening when you are running form.loadRecord(rec).

    1. you set the FoodGroup combobox
    2. you set the FoodName combobox. BUT the value is not there, because your filter did not switch to appropriate food groups. That is why commenting force selection helps. (That is why commenting filter also help).
    3. turned on the filter of food names. Store now have new values.

    You are clicking the button second time. The first combobox value is the same, filters are not trigged (triggered?), you already have appropriate values in the second store and the value is selected.

    How to fix: The fix is ugly. You can listen on store 'refresh' (it means the filters are triggered) and then set the second value (or set the values again).

    Ext.define('Fiddle.view.FormModel', {
        extend: 'Ext.app.ViewModel',
        alias: 'viewmodel.fiddle-form-model',
        stores: {
            foodgroups: {
                fields: ['name'],
                data: [{
                    foodgroupname: 'Fruits'
                }, {
                    foodgroupname: 'Vegetables'
                }]
            },
            foods: {
                fields: ['foodgroupname', 'foodname'],
                filters: {
                    property: 'foodgroupname',
                    value: '{selectedFoodgroup.foodgroupname}'
                },
                data: [{
                    foodname: 'Apple',
                    foodgroupname: 'Fruits'
                }, {
                    foodname: 'Banana',
                    foodgroupname: 'Fruits'
                }, {
                    foodname: 'Lettuce',
                    foodgroupname: 'Vegetables'
                }, {
                    foodname: 'Carrot',
                    foodgroupname: 'Vegetables'
                }]
            }
        }
    });
    
    Ext.define('Fiddle.view.Form', {
        extend: 'Ext.form.Panel',
        xtype: 'fiddle-form',
        viewModel: {
            type: 'fiddle-form-model'
        },
    
        title: 'Combos',
        items: [{
            xtype: 'combo',
            itemId: 'FoodGroup', // To access FoodGroup
            displayField: 'foodgroupname',
            bind: {
                store: '{foodgroups}',
                selection: '{selectedFoodgroup}'
            },
            valueField: 'foodgroupname',
            forceSelection: true,
            name: 'foodgroup',
            fieldLabel: 'Food Group',
            value: 'Vegetables'
        }, {
            xtype: 'combo',
            itemId: 'FoodName', // To access FoodName
            bind: {
                store: '{foods}'
            },
            queryMode: 'local',
            forceSelection: true, //COMMENTING THIS OUT ACHIEVES DESIRED LOAD RECORD BEHAVIOR
            displayField: 'foodname',
            valueField: 'foodname',
            name: 'food',
            fieldLabel: 'Food',
            value: 'Carrot'
        }],
    
        buttons: [{
            text: 'Load Record',
            handler: function (btn) {
                // OUR UGLY FIX
                var form = btn.up('form'),
                    foodGroupComboBox = form.down('combobox#FoodGroup'),
                    foodNameComboBox = form.down('combobox#FoodName'),
                    record = Ext.create('Ext.data.Model', {
                        foodgroup: 'Fruits',
                        food: 'Apple'
                    });
                foodNameComboBox.getStore().on('refresh', function (store) {
                    form.loadRecord(record);
                }, this, {
                    single: true
                })
    
                form.loadRecord(record);
            }
        }]
    
    });
    
    Ext.application({
        name: 'Fiddle',
    
        launch: function () {
    
            var form = new Fiddle.view.Form({
                renderTo: document.body,
                width: 600,
                height: 400
            });
    
        }
    });