12
votes

I am using ListFilter plugin to filter results on a Grid panel. The column definition is.

{
    header: 'Provider',
    filter: {
        type: 'list',
        store: Ext.getStore('MyApp.store.Provider'),
        dataIndex: 'provider_id',
        labelField: 'name'
    }
}

MyApp.store.Provider is created as

   Ext.create('Ext.data.Store', {
        storeId: 'MyApp.store.Provider',
        autoDestroy: true,
        autoLoad: {start: 0, limit: 50},
        autoSync: true,
        model: 'MyApp.model.Provider',
        pageSize: 50,
        proxy: {
            type: 'ajax',
            api: {
                create:  'proxy/provider/create',
                read:    'proxy/provider/read',
                update:  'proxy/provider/update',
                destroy: 'proxy/provider/destroy'
            },
            reader: {
                type: 'json',
                root: 'data',
                successProperty: 'success',
                messageProperty: 'message',
                totalProperty: 'total'
            },
            writer: {
                allowSingle: false,
                type: 'json',
                writeAllFields: false,
                root: 'data'
            }
        }
    });

And lastly model MyApp.model.Provider is defined as

Ext.define('MyApp.model.Provider', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'provider_id', type: 'int'},
        'name',
        { name: 'create_time', type: 'date', dateFormat: appDateFormat },
        { name: 'status', type: 'int'}
    ],
    idProperty: 'provider_id',
    displayProperty: 'name' // A custom property used for dynamically use the property to display
})

Now this code does not show any sub-menu in the filter menu. It just shows loading. See the image.

shows loading

Update

I have solved it using following filter config. This actually populates options config manually. So no store is used here.

{
  type: 'list',
  labelField: 'name',
  options: (function () {
    var opts = [];
    fS.load(function (records, operation, success) {
      for (var i = 0; i < records.length; i++) {
        var ar = {
          id: records[i].get('provider_id'),
          name: records[i].get('name')
        };

        opts.push(ar);
      }
    });
    return opts;
  })(),
  single: true
}

It seems 'id' is hard-coded. id: records[i].get('provider_id'), does not look good. Though it works.

But I am still looking for a proper way to do it.

Note: The expected behavior can be found on ExtJS 4.1.1. See this jsfiddle. I have reproduced it. But this very same thing does not work on ExtJS 4.0.7

1
possible duplicate of Extjs Grid Filter - Dynamic ListFilter. You could try that other answer and see if it works - the one that isn't mine (I haven't tried it myself so I'm not sure) I went with an alternative. - egerardus
This is not a duplicate. Other answer are hacky. Nothing standard. Also they didn't work for me. - Shiplu Mokaddim
I would retract my "dup" vote if I could now that I understand. This may have been fixed with 4.1.3 but when I was trying to handle this in 4.1.0 it seemed like something broken in the framework so hack solutions were the only things available. - egerardus
@shiplu.mokadd.im I created an override for this to make it work properly with something like the 'idField' config option. Not sure if you are still interested in that or not, but since it's homebrewed, may be good for ya as it is not proprietary code from sencha. Drop me a comment if you want it. I had done it because I ran into the same issue when we were first using 4.0.7 and then updated when we went to 4.1.0 - Reimius

1 Answers

8
votes

I didn't tried this myself but you need to set the ID manually with the idField property [new to ExtJS4.1.3] which is per default set to id. So I guess this will work:

{
    header: 'Provider',
    filter: {
        type: 'list',
        idField: 'provider_id',
        store: Ext.getStore('MyApp.store.Provider'),
        dataIndex: 'provider_id',
        labelField: 'name'
    }
}

Update

OK, I looked at the source and I can now tell you that this is the answer. So will have to either live with your workarround until 4.2 is out or you can apply the following changes to your Ext.ux.grid.menu.ListMenu to make it run:

add the idField with a default value.

look within the constructor for this lines

case 'object': options.push([value.id, value[this.labelField]]); break;
// some more lines
fields: ['id', this.labelField],

and replace it with

case 'object': options.push([value[me.idField], value[me.labelField]]); break;
// some more lines
fields: [me.idField, me.labelField],

and within the onLoad function look for

itemValue = records[i].get('id');

and replace it with

itemValue = records[i].get(me.idField);

and that pretty much is it.