0

I want to add filter to my grid that is paged locally.

The problem that I am facing is that this implementation only filters on the current page of the grid and not the whole store data associated with the grid.

Is there any work around by using a filter on a proxy ? or any way to make it filter work on the complete store data.

Thanks in advance.

Below is my Grid:

Ext.define('MyApp.view.grid.FAQGrid', {
    extend: 'Ext.grid.Panel',

    xtype: 'faqQuesGrid',   
    store: 'faqQuestionsStore',
    title: 'FAQ',

    columnLines: true,
    stripeRows: true,

    columns: {
        defaults:
        {
            resizable: false
        },
        items:
        [{
            header: 'Title',
            dataIndex: 'title',
            width: '77%'
        },
        {
            header: 'Category',
            dataIndex: 'categoriesName',
            width: '10%',
            renderer: function(value) {
                return '<a href="#">' + value + '</a>';
            }
        },
        {
            header: 'Published Date',
            dataIndex: 'publishedDate',
            width: '11.5%'
        }]
    },

    plugins: [{
        ptype: 'rowexpander',
        pluginId: 'faqRowId',

        rowBodyTpl: new Ext.XTemplate (
            '<p><b>Question: </b> {question}</p>',
            '<p><br/><b>Answer: </b>',
                '<tpl if="writtenAnswer">',
                    '{writtenAnswer}',
                '</tpl>',
                '<tpl if="videoAnswer">',
                    '{videoAnswer}',
                '</tpl>',
            '</p>',
             '<p><br/><i><b>Posted on</b> {publishedDate} | <b>Filed Under</b>: {categoriesName}</i></p>',
            '<tpl if="searchTagsName">',
                '<p><i><b>Tags</b>: ',
                    '<tpl for="searchTagsName">',
                        '{.};',
                    '</tpl>',
                '</i></p>',
            '</tpl>' 
        )
    }],

    tools:
    [{
        xtype: 'button',
        text: 'Expand All',
        itemId: 'expandButtonId',
        iconAlign: 'left',
        style: 'margin: 5px'
    },{
        xtype: 'button',
        text: 'Collapse All',
        itemId: 'collapseButtonId',
        iconAlign: 'left',
        style: 'margin: 5px'
    },{
        xtype: 'textfield',
        itemId: 'searchItem',
        allowBlank: false,
        emptyText: 'Search FAQ',
        style: 'margin: 5px'
    },{
        baseCls: 'search-icon',
        itemId: 'searchIconId',
        height: 20,
        iconAlign: 'right',
        tooltip: 'Search Grid',
        style: 'margin: 5px'
    }],

    dockedItems: 
    [{
        xtype: 'pagingtoolbar',
        dock: 'bottom',
        store: 'faqQuestionsStore',
        itemId: 'faqPagingToolbarId',
        displayInfo: true,
        displayMsg: 'Displaying questions {0} - {1} of {2}',
        emptyMsg: "No questions to display",
    }],

    listeners: {
        cellclick : function(grid, rowIndex, cellIndex, record, e) {
            if(cellIndex == 2){
                var clickedDataIndex = grid.headerCt.getGridColumns()[cellIndex].dataIndex;
                var clickedCellValue = record.get(clickedDataIndex);
                MyApp.app.getController('MyApp.controller.CategoriesController').getCategoryQuestions(clickedCellValue);
            }
        }
    }
});

Store:

Ext.define('MyApp.store.FAQQuestionsStore', {
    extend: 'Ext.data.Store',
    model: 'MyApp.model.QuestionsModel',
    requires: [
            'MyApp.model.QuestionsModel'
            ],

    storeId: 'faqQuestionsStore',
    autoLoad: false,
    remoteSort: true,
    remoteFilter: false,

    pageSize: 25,

    proxy: {
        type: 'memory',
        enablePaging: true,

        reader: {
            type: 'json'
        }
    }   
});

I am performing filtering as below:

this.control({
            'faqQuesGrid #searchItem':{
                change: this.filterQuestions
            }
}); 

filterQuestions: function(textfield) {
        var grid = textfield.up('panel');
        var store = grid.getStore();
        if(store != null) {
            //clear filters first
            store.remoteFilter = false;
            store.clearFilter(true);

            var filters = new Array();

            //add filter to filter array
            if(textfield.isValid()){
                var searchTxt = textfield.getValue();

                //create filter and add to filters array
                var questionFilter = {
                    property: 'question',
                    anyMatch: true,
                    caseSensitive: false,
                    value   : searchTxt
                };

                filters.push(questionFilter);
            } else{
                 store.read();
            } 
            //else condition is necessary to populate the grid correctly when a search query is removed

            //add filters to store
            if(filters.length > 0){
                store.addFilter(filters);
            }
        }
    },

//to remove any filters added when we leave this page to prevent issues with other page functionality
deactivate: function(){
                    var store = Ext.getStore('faqQuesStore');
                    if(store != null){
                        store.clearFilter();
                    }

                }
Kartik
  • 3
  • 1
  • 4
  • You need to set `remoteFilter: true`. – Evan Trimboli Oct 27 '14 at 19:41
  • Hi Evan, Thanks for the solution. Setting remoteFilter as true, doing local paging and filtering is possible..However, as I understood from the API docs, this config is set true for server side operations. Can you please explain briefly on this ? Thanks – Kartik Oct 27 '14 at 20:41
  • 2
    The filtering is happening "remotely" in the proxy. It acts like a server. Filtering locally means do the filtering in the store. Remote means have it handled by the proxy. – Evan Trimboli Oct 27 '14 at 21:05
  • ok..That explains it. – Kartik Oct 27 '14 at 21:08
  • @Evan - I updated Sencha from 5.0.0 to 5.1.3 and this solution doesn't work. It looks like when remoteFilter: true, I am not able to apply a local filter to my store.. – Kartik Sep 15 '16 at 21:36
  • I figured out. Moving to 5.0.1 made it work as before. – Kartik Sep 23 '16 at 15:53

1 Answers1

0

As Evan Trimboli mentioned in the comments to your question, you have to set remoteFilter: true for store to filter entire data set using memory proxy.

The filtering is happening "remotely" in the proxy. It acts like a server. Filtering locally means do the filtering in the store. Remote means have it handled by the proxy.

I want to note that Ext.data.proxy.Memory.read use Ext.util.Filter.createFilterFn to create a filter function based on passed Ext.util.Filter[] (with property-value configs):

// Filter the resulting array of records 
if (filters && filters.length) {
    // Total will be updated by setting records 
    resultSet.setRecords(records = Ext.Array.filter(records, Ext.util.Filter.createFilterFn(filters)));
    resultSet.setTotal(records.length);
}

So, if you want to use different filter logic, you can override memroy proxy read method and use custom function to create filter function. Check this answer for example.

Sergey Novikov
  • 4,096
  • 7
  • 33
  • 59