ArtSoftSolutions

ExtJS PagingMemoryProxy Filter

An article by Robert

The ExtJS PagingMemoryProxy extension is very good to use it when you want to load data in a component and handle it locally, using javascript. I see others using it when they have to load small amounts of data (less than 15KB), or when the data really takes a lot of resources from MySql to be assembled on each pagination and it's easier to have all the data at once and then perform different operations with it on client computer. On the other hand, the PagingMemoryProxy extensions takes quite some memory resources on the client side and since it loads all the data at once, is not recommended for large amounts of data.

There are quite a few versions of PagingMemoryProxy on the Internet, and the one from Sencha forums is not updated.

When deciding to use this extension in your project, make sure you have the following piece of code in it, code required by our mutual friend - Internet Explorer.

if (!Array.prototype.filter){
  Array.prototype.filter = function(fun /*, thisp*/){
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++){
      if (i in this){
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }
    return res;
  };
}

Also, for a proper use of filtering, you have to set two parameters to use with PagingMemoryProxy:

  • filter
  • filterCol

Make sure you set filter and filterCol properly as baseParams in the beforeload event of the store in order to make them persistent. The code i'm using for filtering, in PagingMemoryProxy extension is the following:

// filtering
if (params.filter !== undefined && params.filter != '') {
result.records = result.records.filter(function(el){
if (typeof(el) == 'object') {
var att = params.filterCol || 0;
return String(el.data[att]).toLowerCase().match(String(params.filter).toLowerCase()) ? true : false;
}
else {
return String(String(el).toLowerCase()).match(String(params.filter).toLowerCase()) ? true : false;
}
});
result.totalRecords = result.records.length;
}

 

In order to remove filtering, just set filter as null or as an empty string.

You could have the previous code block several times for any other filters - like SearchField (with a query parameter and another one for the queried column(s)), or even with GridFilters extension, like in the code below (where it uses a columnfilter parameter which is encoded as JSON). Both SearchField and GridFilters are included in the default ExtJS 3.2.1 archive file in /examples/ux/ folder.

In the code below we are showing the code for "numeric" and "list" type only, but GridFilters extension offers more filter types.

        if (params.columnfilter !== undefined) {
//columnfilter is a json-encoded filter string
//used for integration with GridFilters plugin
var filters = Ext.util.JSON.decode(params.columnfilter);

Ext.each(filters, function(myFilter, idx) {

result.records = result.records.filter(function(el){
if (typeof(el) == 'object') {
var att = myFilter.field || 0;
switch (myFilter.type){
case "list":
var myArray = String(myFilter.value).split(',');
return in_array(el.data[att], myArray) ? true : false;
break;
case "numeric":
switch (myFilter.comparison){
case "eq": return (el.data[att] === myFilter.value) ? true : false; break;
case "lt": return (el.data[att] < myFilter.value) ? true : false; break;
case "gt": return (el.data[att] > myFilter.value) ? true : false; break;
}
break;
}
}
else {
switch (myFilter.comparison){
case "eq": return (el === myFilter.value) ? true : false; break;
case "lt": return (el < myFilter.value) ? true : false; break;
case "gt": return (el > myFilter.value) ? true : false; break;
}
}
});
result.totalRecords = result.records.length;
});
}

 

After playing with PagingMemoryProxy for a while and implementing it in some screens of my application, i decided to remove it due to some unexpected behavior with large amount of data (AJAX requests greater than 15-20KB) in Safari and Internet Explorer. Things were working properly in Firefox and Chrome.

Basically, those browsers didn't raise any error, but didn't show the data. This must be some sort of built-in limitation for which i could not find a workaround, so it was easier to switch back to standard pagination and HttpProxy.

 

Add comment


Security code
Refresh

You are here: Home Tips&Tricks ExtJS ExtJS PagingMemoryProxy Filter