Getting EXT PagingToolbars to save state

A problem that has recently had me pulling my hair out is how to save state in an EXT PagingToolbar.

Ext makes it easy to save the state of most of its components - by default it does this by setting a cookie with the relevant configuration info, then just reading it back when you load the component again. I've been using it to save the state of a few EXT grids I've been using on a recent project, this saves config such as which columns you have visible, which column you're sorting by, and how the columns are ordered.

That works great, and is trivial to implement - just set your provider (see http://extjs.com/deploy/dev/docs/?class=Ext.state.CookieProvider) and be sure to give your grid an id in its config - this is used as the key in the state provider and needs to be unique for each component.

The problem comes when you're using a paging toolbar though, as this does not save state, so every time you view the grid you're back to page 1. You can add state behaviour to the paginator by piggybacking the grid's state store, here's how it's done:


Ext.PagingToolbar.override({
init : function (grid) {
this.grid = grid;
this.grid.on("beforestatesave", this.saveState, this);
Ext.util.Observable.capture(grid.store, this.onStateChange, this);
},
saveState : function(grid, state) {
state.start = grid.store.lastOptions.params.start;
},
onStateChange : function(ev, store, records, options) {
if (ev == "load") {this.grid.saveState(); };
}
});

Ext.PagingToolbar.override({
init : function (grid) {
this.grid = grid;
this.grid.on("beforestatesave", this.saveState, this);
Ext.util.Observable.capture(grid.store, this.onStateChange, this);
},
saveState : function(grid, state) {
state.start = grid.store.lastOptions.params.start;
},
onStateChange : function(ev, store, records, options) {
if (ev == "load") {this.grid.saveState(); };
}
});

Basically we're intercepting the attached Grid's saveState() event and appending the current start value as stored in the Grid's DataStore (e.g. if you're looking at page 3 with 25 rows per page then start = 50). If you examine the contents of your state provider using Firebug (Ext.state.Manager.getProvider().state, then look for the key that matches the id of your grid), you'll see that there is now a record for 'start', which grabbed the correct value from the Grid's store.

All you need to do then is retrieve that value from the state provider and load your store accordingly:


store = new Ext.data.Store({... your store config ...});

grid = new Ext.grid.GridPanel({
id: 'unique_grid_id',
store: store,
... other grid config ...
});

//shorthand way of retrieving state information
var state = Ext.state.Manager.getProvider();

var start = state.get(options.id).start || 0);
store.load({params: {start: start, limit: 25}});

store = new Ext.data.Store({... your store config ...});

grid = new Ext.grid.GridPanel({
id: 'unique_grid_id',
store: store,
... other grid config ...
});

//shorthand way of retrieving state information
var state = Ext.state.Manager.getProvider();

var start = state.get(options.id).start || 0);
store.load({params: {start: start, limit: 25}});

If the start value for this grid has never been set it'll default to zero - e.g. the first page. Next time you come back to this grid it'll take you right back to where you were, including all column setup and sorting behaviour you have specified.

Share Post:

What to Read Next

For those interested in further enhancing their Ext JS grids, the article on ExtJS grid page size - letting the user decide offers insights into allowing users to select their preferred page size. Additionally, exploring Using Ext.History might be beneficial, as it covers managing navigation with browser history in AJAX applications.