1
votes

I have a grid with a combobox editor. I want to filter the combobox store according to a value in the row's record.

What I got now is this:

editor: {
    xtype: 'combo',
    forceSelection: true,
    store: 'ship.Transportmodes',
    displayField: 'name',
    valueField: 'id',
    queryMode: 'local',
    listeners: {
        expand: function(combo){
            var shipper = combo.up('grid').editingPlugin.activeRecord.get('shipper');
            combo.store.filterBy(function(record){
                console.log(record.get('shippers').indexOf(shipper))
                return record.get('shippers').indexOf(shipper) != -1
            })
        }
    },
    editable: false
}},

This is working, but there is a problem: when the dropdown is showing on the top of the field, the remaining options appear far from the field, the space for the removed options is still allotted. screenshot

I tried to filter the store on any of these events:

  • grid : beforeedit
  • combo : beforerender
  • combo : render
  • combo : afterrender

In each case the result is the following: The store gets filtered correctly, but at the time the combobox is expanded, the filter is cleared.

I would like to understand what happens. Why does a combobox always clear the filters of its store before displaying the list of options ?

Can anybody give an insight behind the scenes ? Or tell me what I'm missing in the picture ?

2
You can try clearFilterOnBlur:false so that the filter isn't cleared.Alexander
@alexander Thanks, I will try it. I saw this config, but I thought it would only change the behavior while blurring the combo.Lorenz Meyer
@alexander No, unfortunately this doesn't help. The clearFilterOnBlur only applies to the filter used by typing.Lorenz Meyer

2 Answers

4
votes

You can do like this:
Fiddle link:https://fiddle.sencha.com/#fiddle/1hle

Ext.application({
    name : 'Fiddle',

    simpsonsStore : Ext.create('Ext.data.Store', {
        storeId : 'simpsonsStore',
        fields : ['name', 'email'],
        data : [
            {name : 'Lisa',email : '[email protected]',id:1}, 
            {name : 'Bart', email : '[email protected]',id:2}, 
            {name : 'Homer', email : '[email protected]',id:3},
            {name : 'Marge',email : '[email protected]',id:4}]
    }),

    tagfieldstore : Ext.create('Ext.data.Store', {
        fields : ['tag', 'field'],
        data : [
            {aid:1,tag : 'tag1',field : 'lisa record1'}, 
            {aid:1,tag : 'tag3',field : 'lisa record2'}, 
            {aid:3,tag : 'tag1',field : 'homer record3'}, 
            {aid:3,tag : 'tag3',field : 'homer record4'},
            {aid:2,tag : 'tag1',field : 'bart record1'}, 
            {aid:2,tag : 'tag3',field : 'bart record2'}, 
            {aid:4,tag : 'tag1',field : 'marge record3'}, 
            {aid:4,tag : 'tag3',field : 'marge record4'}]
    }),

    launch : function() {

        Ext.create('Ext.grid.Panel', {
            title : 'Simpsons',
            store : this.simpsonsStore,
            columns : [{
                flex :1 ,
                text : 'Name',
                dataIndex : 'name',
            }, {
                text : 'Email',
                dataIndex : 'email',
                flex : 1
            }, {
                xtype : 'widgetcolumn',
                cellWrap : true,
                text : 'Phone',
                flex : 1,
                widget : {
                    xtype: 'combo',
                    store : this.tagfieldstore,
                    valueField : 'tag',
                    displayField : 'field',
                    growMax : true, 
                    listeners:{
                       expand:function(combo){
                           combo.store.clearFilter();
                          var id = combo.$widgetRecord.data.id;
                           combo.store.filterBy(function(rec){
                                return rec.data.aid == id;
                          });
                       }
                    }

                }
            }],
            flex : 1,
            renderTo : Ext.getBody()
        });
    }
});
2
votes

Finally I figured it out. The problem was not that ExtJs is clearing filters on a combobox' store. The problem came from a missunderstanding of the working of filters. In fact filterBy filters the store only temporarily, but does not save that filter in the store.

On the other hand, addFilter({filterFn: ...}) adds the filter to the store's filters collection.

Filters that are added on a store with addFilter will still apply after rendering that combobox, filters that are applied with filterFn are volatile.

Now I can add the filter on grid's beforeedit event, and remove it on edit and canceledit.

favorite

I have a grid with a combobox editor. I want to filter the combobox store according to a value in the row's record.

What I got now is this:

editor: {
    xtype: 'combo',
    forceSelection: true,
    store: 'ship.Transportmodes',
    displayField: 'name',
    valueField: 'id',
    queryMode: 'local',
    // no listener here
    editable: false
}

Controller:

onBeforeedit: function(edit, e){
    this.getStore('mystore').addFilter(
        {id: 'shipperFilter', 
        filterFn: function(record){
            return e.record.get('shippers').indexOf(this.shipper) != -1
        }
    })
}