ExtJS Infinite Scroll Grid with remote Filters and Sort
Your answer provided the right direction, I modified your code from
store.loadRecords(Ext.Array.slice(records, 0, count));
to
store.loadRecords(Ext.Array.slice(records, 0, records.length));
This fixed an issue of your previous filter returning empty results. After I inserted this change it was working correctly.
SUCCESS! I have infinite scrolling working with a remote filter and remote sort (this is in 4.1 beta 2, but because I was getting the same errors in 4.02a and 4.0.7 I imagine that it would resolve those too). Basically, I just had to add a few overrides in my code.
I haven't done testing in other browsers but I have it going in FF. Here are the overrides that I am using:
Ext.override(Ext.data.Store, {
// Handle prefetch when all the data is there and add purging
prefetchPage: function(page, options, forceLoad) {
var me = this,
pageSize = me.pageSize || 25,
start = (page - 1) * me.pageSize,
end = start + pageSize;
// A good time to remove records greater than cache
me.purgeRecords();
// No more data to prefetch
if (me.getCount() === me.getTotalCount() && !forceLoad) {
return;
}
// Currently not requesting this page and range isn't already satisified
if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) {
me.pagesRequested.push(page);
// Copy options into a new object so as not to mutate passed in objects
options = Ext.apply({
page : page,
start : start,
limit : pageSize,
callback : me.onWaitForGuarantee,
scope : me
}, options);
me.prefetch(options);
}
},
// Fixes too big guaranteedEnd and forces load even if all data is there
doSort: function() {
var me = this;
if (me.buffered) {
me.prefetchData.clear();
me.prefetchPage(1, {
callback: function(records, operation, success) {
if (success) {
guaranteeRange = records.length < 100 ? records.length : 100
me.guaranteedStart = 0;
me.guaranteedEnd = 99; // should be more dynamic
me.loadRecords(Ext.Array.slice(records, 0, guaranteeRange));
me.unmask();
}
}
}, true);
me.mask();
}
}
});
Ext.override(Ext.ux.grid.FiltersFeature, {
onBeforeLoad: Ext.emptyFn,
// Appends the filter params, fixes too big guaranteedEnd and forces load even if all data is there
reload: function() {
var me = this,
grid = me.getGridPanel(),
filters = grid.filters.getFilterData(),
store = me.view.getStore(),
proxy = store.getProxy();
store.prefetchData.clear();
proxy.extraParams = this.buildQuery(filters);
store.prefetchPage(1, {
callback: function(records, operation, success) {
if (success) {
guaranteeRange = records.length < 100 ? records.length : 100;
store.guaranteedStart = 0;
store.guaranteedEnd = 99; // should be more dynamic
store.loadRecords(Ext.Array.slice(records, 0, guaranteeRange));
store.unmask();
}
}
}, true);
store.mask();
}
});
My store is configured like so:
// the paged store of account data
var store = Ext.create('Ext.data.Store', {
model: 'Account',
remoteSort: true,
buffered: true,
proxy: {
type: 'ajax',
url: '../list?name=accounts', //<-- supports remote filter and remote sort
simpleSortMode: true,
reader: {
type: 'json',
root: 'rows',
totalProperty: 'total'
}
},
pageSize: 200
});
The grid is:
// the infinite scroll grid with filters
var grid = Ext.create('Ext.grid.Panel', {
store: store,
viewConfig: {
trackOver: false,
singleSelect: true,
},
features: [{
ftype: 'filters',
updateBuffer: 1000 // trigger load after a 1 second timer
}],
verticalScrollerType: 'paginggridscroller',
invalidateScrollerOnRefresh: false,
// grid columns
columns: [columns...],
});
Also the initial load must be done like this (not just store.load()):
store.prefetch({
start: 0,
limit: 200,
callback: function() {
store.guaranteeRange(0, 99);
}
});