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?
source to share
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);
}
...
}
}
});
source to share
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.
source to share