0
votes

I have 2 combo box inside grid. The second combo box value will be change base on first combo box.

For example the combo has 3 item : America, Europe, Asia.
If in the first combo box Europe is selected, then in the second combo box, Europe is not appear again.

I don't know which version of extjs I used,

but here's the code :

MY COMBO STORE

var cb_group = Ext.create('Ext.data.Store', {
model: 'cb_group',
autoLoad: false,
proxy: {
    type: 'ajax',
    url: 'srv/master/group/combo',
    reader: {
        type: 'json',
        root: 'rows'
        }
    }
});


MY COMBO INSIDE GRID

var set_approval_dtl = Ext.create('Ext.Window', {
title: title_approval2, width: 850, height: 395, rowdblclick: true, forceFit: true,
closeAction: "hide", store: ms_set_approval_dtl_store,
defaults: {
    sortable: true, resizable: false
},
items: [
    {xtype: "form", items: [
            {layout: 'column', columnWidth: .5, itemId: 'set_approve', defaults: {border: false},
                items: [{xtype: "panel", itemId: "set_approve_panel", height: 330, defaultType: 'textfield', margin: '0 10px 0 10px',
                        defaults: {labelWidth: 120, width: 850, maxLength: 200},
                        items: [
                            {xtype: "grid", itemId: "grid_items", width: 782, height: 280, margin: '0 10px 10px 10px', autoScroll: true,
                                plugins: Ext.create('Ext.grid.plugin.CellEditing', {clicksToEdit: 1, pluginId: 'rowEditing'}),
                                store: ms_set_approval_dtl_store, stripeRows: true, defaultType: "gridcolumn",
                                viewConfig: {forceFit: true},
                                columns: [
                                    {header: grid18j, width: 150, dataIndex: 'nm_act', align: 'center'},
                                    {header: subtitle_approval3, width: 126, dataIndex: 'level1', align: 'center',
                                        editor: {xtype: "combobox", name: "cdgr", itemId: "cdgr1", typeAhead: true, editable: false, triggerAction: "all", forceSelection: true,
                                            emptyText: grid8k, store: cb_group, valueField: "id", displayField: "nm",
                                            listeners: {
                                                expand: function(field, options, val) {
                                                    if (Ext.typeOf(field.getPicker().loadMask) !== "boolean") {
                                                        field.getPicker().loadMask.hide();
                                                    }
                                                },
                                                select: function(value) {
                                                    var obj = this.lastSelection[0].data;
                                                    return obj.nm;
                                                    this.lastSelection[0].hide;
                                                    cb_group.removeAt(0);
                                                }
                                            }},
                                        renderer: function(val) {
                                            var index = cb_group.findExact('id', val);
                                            if (index !== -1) {
                                                var rs = cb_group.getAt(index).data;
                                                return rs.nm;
                                            }
                                        }
                                    },
                                    {header: subtitle_approval4, width: 126, dataIndex: 'level2', align: 'center', itemId: "level2",
                                        editor: {xtype: "combobox", name: "cdgr", itemId: "cdgr2", typeAhead: true, editable: false, triggerAction: "all", forceSelection: true,
                                            emptyText: grid8k, store: cb_group, valueField: "id", displayField: "nm",
                                            listeners: {
                                                expand: function(field, options) {
                                                    if (Ext.typeOf(field.getPicker().loadMask) !== "boolean") {
                                                        field.getPicker().loadMask.hide();
                                                    }
                                                }
                                            }
                                        },
                                        select: function(value) {
                                            var obj = this.lastSelection[0].data;
                                            return obj.nm;
                                        },
                                        renderer: function(val) {
                                            var index = cb_group.findExact('id', val);
                                            if (index !== -1) {
                                                var rs = cb_group.getAt(index).data;
                                                return rs.nm;
                                            }
                                        }
                                    }]
                            }]}
                ]}]}
]});


I've tried this.lastSelection[0].hide; and cb_group.removeAt(0); in the first combo. But it didn't work at all. And I dont know why my select listener is not working.
please share some solution. Thanks

2

2 Answers

0
votes

You can use XTemplates to manage this kind of behavior with one store and two comboboxes.

At first you have to create an XTemplate for your list of items in the combobox:

// displayfield = displayfield configured in your combobox
var template = Ext.create('Ext.XTemplate',
  '<tpl for=".">',
  '  <tpl if="[Ext.getCmp(\'combobox1\').getValue()] != id && [Ext.getCmp(\'combobox2\').getValue()] != id">',
  '    <div class="x-boundlist-item">{label}</div>',
  '  <tpl else>',
  '    <tpl if="id == null || id == \'\'">',
  '      <div class="x-boundlist-item">{label}</div>',
  '    <tpl else>',
  '      <div class="x-boundlist-item" style="font-size:0px; height:0px;"></div>',
  '    </tpl>',
  '  </tpl>',
  '</tpl>'
);

The XTemplate contains some statements to check if the specific value is already selected in one of the comboboxes. If not, then the entry will appear in the dropdown list, otherwise it will be hidden. To make it work, you have to set the template in your combobox and add some listeners to them:

// Combobox 1
{
    xtype: 'combo',
    id: 'combobox1',
    store: 'your_store',
    tpl: template,
    displayField: 'label',
    valueField: 'id',
    listeners: {
    beforeSelect: function (combo, record, index, eOpts)
    {
        // Check if the selected value is already selected in combobox2
        var cbx2value = !!Ext.getCmp('combobox2').getValue() ? Ext.getCmp('combobox2').getValue() : '';

        if (cbx2value != record.get('id') && cbx2value != record.get('id')) {
            return true; // selected entry will be selected successfully
        } else {
            return false; // selected entry will not be selected
        }
    },
    change: function ()
    {
        // Get the picker (list of items) of the other combobox and refresh it's template state
        var cbx2picker = Ext.getCmp('combobox2').getPicker();
        cbx2picker.refresh();
    }
}

// Combobox 2
{
    xtype: 'combo',
    id: 'combobox2',
    store: 'your_store',
    tpl: template,
    displayField: 'label',
    valueField: 'id',
    listeners: {
    beforeSelect: function (combo, record, index, eOpts)
    {
        // Check if the selected value is already selected in combobox2
        var cbx1value = !!Ext.getCmp('combobox1').getValue() ? Ext.getCmp('combobox1').getValue() : '';

        if (cbx1value != record.get('id') && cbx1value != record.get('id')) {
            return true; // selected entry will be selected successfully
        } else {
            return false; // selected entry will not be selected
        }
    },
    change: function ()
    {
        // Get the picker (list of items) of the other combobox and refresh it's template state
        var cbx1picker = Ext.getCmp('combobox1').getPicker();
        cbx1picker.refresh();
    }
}

It's not the ultimate solution, but for one of my projects it worked like a charm. I have simplified the example as good as possible to make the solution clearer.

-1
votes

You will need two stores, one for each combo box, both filled with the same data.

And then you will do:

combo1.on('select',function(combo, newVal) {
    combo2.getStore().filterBy(function(rec){
        return rec.get("value")!=newVal;
    })
});