ExtJS 6 Use Custom Filter Function in Memory Proxy

I have a store configured with a memory proxy with enablePaging: true

. Store remoteFilter

and remoteSort

in true

to filter and sort requests processed by the proxy.

When I filter my store with multiple fields, I want to use the OR condition, not AND.

Without paging the memory proxy, I could use remoteFilter: false

the custom filter function as well, e.g .:

store.filterBy(function (record)
{
    for (var i = 0; i < searchFields.length; ++i) {
        if (record.get(searchFields[i]).toLowerCase().indexOf(searchText) !== -1) {
            return true;
        }
    }
    return false;
});

      

But how can I achieve this with paging? Override memory proxy?

+3


source to share


2 answers


Ext.data.proxy.Memory.read use Ext.util.Filter.createFilterFn to create a filter function based on the passed Ext.util.Filter [] (with property configurations):

// 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 the memroy proxy read method and use a custom function to create the filter function:

Ext.define('MyApp.extensions.FilterMemoryProxy', {
    extend: 'Ext.data.proxy.Memory',
    alias: 'proxy.filtermemory',

    createCustomFilterFn: function (filters)
    {
        if (!filters) {
            return Ext.returnTrue;
        }
        return function (candidate)
        {
            var items = filters.isCollection ? filters.items : filters,
                length = items.length,
                i, filter;
            for (i = 0; i < length; i++) {
                filter = items[i];
                if (!filter.getDisabled() && candidate.get(filter.getProperty()).toLowerCase().indexOf(
                        filter.getValue().toLowerCase()) !== -1) {
                    return true;
                }
            }
            return false;
        };
    },

    read: function (operation)
    {

        ...

        if (operation.process(resultSet, null, null, false) !== false) {
            // Filter the resulting array of records
            if (filters && filters.length) {
                // Total will be updated by setting records
                resultSet.setRecords(records = Ext.Array.filter(records, me.createCustomFilterFn(filters)));
                resultSet.setTotal(records.length);
            }

        ...

        }
    }
});

      

+2


source


You can override the proxy server memory to suit your needs or if you want only to find a line in one of the fields specified in searchFields

, you can add to the model a "virtual" field using convert

.

For example:

// Extend Ext.data.Model or create it. Dealer choice.
Ext.define('MyLocalModel', {
    extend: 'Ext.data.model',
    fields: [
        ...
        {
            name: 'searchField',
            type: 'string',
            convert: function(value, record) {
                // Get search fields somewhere
                var resultArray = [];
                for (var i = 0; i < searchFields.length; ++i) {
                    var searchField = searchFields[i];
                    var fieldValue = record.get(searchField);
                    resultArray.push(fieldValue);
                }

                // Join by a string that would not normally be searched
                // so that field values 'foo' and 'bar' are not valid when searching 'ooba'
                var result = resultArray.join('**');
                return result;
            }
        }
    ]
});

      



All you have to do in the store is:

store.filter('searchField', searchText);

      

This isn't exactly what you're looking for, but it should get the job done.

0


source







All Articles