Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remote Filtering with ListFilter in ExtJS Grid Column Header

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

like image 793
Shiplu Mokaddim Avatar asked Feb 27 '13 20:02

Shiplu Mokaddim


1 Answers

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.

like image 114
sra Avatar answered Oct 06 '22 16:10

sra