In this article I will demonstrate how to add a pager control to your basic grid.
Demonstration
The EXTJS in XPages demonstration database can be found at http://demo.xomino.com/xomino/Extjs.nsf/xGridWithPager.xsp
Download
The sample database that will accompany this series is available from the menu in the live demo database from this link – http://demo.xomino.com/xomino/Extjs.nsf
Introduction
As we saw from the previous articles we can make a basic EXTJ grid from a REST service. Loading a huge number of documents into an EXTJS grid does have its drawbacks though:
- Poor user experience to have to search down through hundreds of records
- Browser memory management issues.
Too many documents? *Warning*
Unlike traditional notes which allows for a personal cache of data for the user through the notes client, the web browser is not capable of doing this. Any browser (some worse than others) is going to run into problems when you load a significant amount of data on a page. In my experience the worst browser for this is the XPiNC browser (Firefox 3.5 code base), then IE then Firefox and Chrome.
As the developer you also have to consider:
- load time
- how long will it take to load hundres of documents from the REST service over your network
- parsing time for the grid library
- The EXTJS code has to take the JSON and create from it a gigantic table and add that to the DOM. This takes time and browser resources – too slow and the user gets impatient.
Recommendation
If you have more than 250 documents do not load them all into the grid at any one time. For all of the reasons above, starting with the user experience. While Notes Client or Excel may be able to allow a user to manage thousands of records, a web browser is not – find a better way.
Adding a Paging toolbar
There are only a couple of steps to adding a paging toolbar to the bottom of your grid.
First we need to add a property to the store – so that the grid knows how many documents are coming in
var store = Ext.create('Ext.data.Store', { autoLoad: true, autoDestroy: true, autoSync: true, model: 'Person', proxy: { type: 'rest', url: 'xRestService.xsp/byFirstName?count=25', // ?count=25 sets the number of docs the REST sends each time reader: { type: 'json', root: 'items', totalProperty : '@toplevelentries' //This comes from the REST service }, writer: { type: 'json' } } });
The REST service provides the @TopLevelEntries – this is the number of documents in the view
{ "@timestamp":"2013-03-02T16:09:08Z", "@toplevelentries":1299, // <---------- "items": [ { "@entryid":"1-66F3A5FE2B2A38CC85257B1B00254E6D", "@position":"1", "firstname":"Adam", "lastname":"Saenz", "address":"2519 Custer Street", "city":"ROCKWOOD (SOMERSET)", etc etc,
We then need to add the code to the EXT.require to include the Paging toolbar
Ext.require([ 'Ext.data.*', 'Ext.grid.*', 'Ext.toolbar.Paging', ]);
and finally add the toolbar to the grid itself by adding it as a property after the columns
// paging bar on the bottom bbar: Ext.create('Ext.PagingToolbar', { store: store, displayInfo: true, displayMsg: 'Displaying topics {0} - {1} of {2}', emptyMsg: "No topics to display" })
And that’s it.
The 1 of 52 is calculated by the grid 1299 documents divided by 25 documents at a time = 52 pages
Custom Control update
We can add the pager to the XPages Custom Control in the same way as previously described in the last article – but in the case we need to add another property – how many documents per page instead of how many documents for the overall feed.
proxy: { type: 'rest', url: '#{javascript:facesContext.getExternalContext().getRequest().getRequestURI()+"/ccREST?count="+compositeData.countNum}', reader: { type: 'json', root: 'items', totalProperty : '@toplevelentries' },
<xe:restService pathInfo="ccREST" id="restServe1" > <xe:this.service> <xe:viewItemFileService defaultColumns="true" viewName="${javascript:compositeData.theViewName}"></xe:viewItemFileService> </xe:this.service> </xe:restService>
In this case you can see we are using the whole ByFirstName view and the generic Custom Control displayed all the columns successfully !
This Custom Control is available in the download database (ccEXTJSGridwithPager)
To many documents – quite right! My first attempt to load 10K person docs failed miserably. Paging is a good thing! On to sorting and filtering!
Jeff,
Will be interesting to hear how your experience with filtering works. If a user filters on something, but all page haven’t been loaded, what is the result? On the surface, it would seem filtering could provide misleading or incomplete results if all data meeting the criteria are not returned as filtered data. If a filter is applied and you page through the grid, does the newly paged data get added to the filter?
Just curious, as I am comparing what I read here against the jqGrid to gather information and user experiences.
Remote filtering is quite possible, feasible and complicated. Call me 🙂
Alan,
I’m taking a managed bean approach, as opposed to using the Ext Lib Rest Control. I’ll post my results, FYI, I have also used jqGrid.
— Jeff
Is @toplevelentries the number of all documents in the view with respect to any Reader restrictions, or simply the number of documents in the view regardless? Just curious, as the old ?readViewEntries would return something like that and it was an incorrect number if Reader fields were in use.
Very interesting.
I am very interested in the management of the remote filters.
There will be post on this topic?
Or is it confidential?
Thank you very much.
I am sorry mate but the remote filtering work we did was part of a client engagement and cannot released on the blog at this time.