extjsextjs-storesextjs7

Ability to filter a store remotely and locally


I am using Ext JS 7.1 Modern, and I want to know if there is a way to filter a store also locally which has remoteFilter: true.

I have tried to explain my case with a Sencha Fiddle and also attached the code below.

The example contains a store that simulates remote filtering to a server by using dynamic data defined in names.json and setting remoteFilter and filters config.

    remoteFilter: true,
    filters: {
        property: 'id',
        value: 1
    }

After the data is retrieved, suppose the user wants to filter the retrieved data locally by typing into the 'search' field. Now, I want to filter the store locally, but since remoteFilter is set to true, the filter that I set sends a request to the server instead of doing local filtering.

Is there a straightforward way to realize this use-case? It feels like a very common use-case that everybody would need, so I wanted to be sure that I am not missing something.

app.js

Ext.define('App.store.TestStore', {
    extend: 'Ext.data.Store',
    alias: 'store.teststore',

    fields: ['id', 'firstName', 'lastName'],

    autoLoad: true,
    proxy: {
        type: 'ajax',
        url: 'names.json',
        reader: {
            type: 'json',
            rootProperty: 'data'
        }
    },

    remoteFilter: true,
    filters: {
        property: 'id',
        value: 1
    }
});

Ext.define('App.controller.TestController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.testcontroller',

    doSearch: function(field) {
        var list = this.lookup('list'),
            store = list.getStore(),
            value = field.getValue();

        var filters = store.getFilters();
        if (Ext.isEmpty(value))
            filters.remove('firstName')
        else {
            filters.add(new Ext.util.Filter({
                property: 'firstName',
                value: value,
                operator: 'in'
            }))
        }
    }
});

Ext.define('App.dataview.TestList', {
    extend: 'Ext.dataview.List',
    xtype: 'testlist',

    store: {
        type: 'teststore'
    },
    itemTpl: '<div class="contact">{id} <b>{firstName} {lastName}</b></div>'
});

Ext.define('App.MainView', {
    extend: 'Ext.Panel',
    controller: 'testcontroller',
    fullscreen: true,

    items: [{
        xtype: 'searchfield',
        ui: 'solo',
        placeholder: 'Search names',
        listeners: {
            buffer: 500,
            change: 'doSearch'
        }
    }, {
        reference: 'list',
        xtype: 'testlist'
    }]

})

Ext.application({
    name: 'App',

    mainView: 'App.MainView',

    launch: function () {

    }
});

names.json

var data = [{
    id: 1,
    firstName: 'Peter',
    lastName: 'Venkman'
}, {
    id: 2,
    firstName: 'Raymond',
    lastName: 'Stantz'
}, {
    id: 3,
    firstName: 'Egon',
    lastName: 'Spengler'
}, {
    id: 4,
    firstName: 'Winston',
    lastName: 'Zeddemore'
}]

var results = data.filter(function(record) {
    if (params.filter) {
        return record.id > params.filter[0].value
    }
})

return {
    "success": true,
    "data": results
}

Thanks in advance


Solution

  • Use the chained store functionality. Filter your main store remotely, then create a chained store based off the main store to apply extra local filters.

    Evan is right. In early version Extjs we can loaded remoteFilter: true, and local filtered data with help method filterBy. Cleared filter local we can call clearFilter method with argument true.

    But in latest version that functional was removed.

    onFilterEndUpdate method

     if (me.getRemoteFilter()) {
    
                me.getFilters().each(function(filter) {
                    if (filter.getInitialConfig().filterFn) {
                        Ext.raise('Unable to use a filtering function in conjunction with ' + 'remote filtering.');
                    }
                });
    
              ....
            }
    

    How to use chainedstore you can see in my fiddle