Data Pagination

Victor Rasputnis edited this page Jan 28, 2013 · 1 revision

Data Pagination

Ext JS facilitates page flipping with the out-of-the box pagination toolbar - Ext.toolbar.Paging (xtype - pagingtoolbar). Each page flip causes a call to store.load(), passing page, start and limit as additional properties of the parameter object, effectively resulting in : store.load({page:nextPage, start:rowToStart, limit:rowsToLoad, …rest of parameter object properties}). However, Ext JS leaves communication with the server entirely in the hands of the developer. That is where CDB Ext JS steps in. Here we discuss how you:

  • turn on/off pagination for a particular store
  • support paginated data feed on the server side
  • use paging toolbar in your view

Enabling Store For Pagination

This is the best part! By Ext JS default, all datastores are enabled for pagination. So is the Clear.data.DirectStore. The default size of the page is 25, as per value of defaultPageSize config property. You can disable pagination prior to construction by assigning 0 to the defaultPageSize config or by assigning -1 to pageSize. The later method can also be used to disable the pagination at the run-time, after the store is constructed. CDB Ext JS will pass pagination information to the server - start, limit, page - only when the pagination for the corresponding store is enabled.

Making Java Method Feed Data Page By PAge

First and foremost: the signature of your Java method does not matter. CDB Ext JS is not expecting that you will modify method parameters or return type. Quite the opposite, it allows you to handle pagination only when needed.

You use static methods of the DirectOptions class to determine if pagination is required or not. Whenever you pass a page of data, you a requires to indicate the size of the entire data set via the same DirectOptions. The following example assumes that dataEngine.getCompanyList() returns the entire data set and illustrates how a methods should be written to accomodate both use cases - one with the pagination and one without it:

public List<CompanyDTO> getCompanies() {
    List<CompanyDTO> companyList = dataEngine.getCompanyList();
    Integer start = (Integer)DirectOptions.getOption("start");
    Integer limit = (Integer)DirectOptions.getOption("limit");
    int total = companyList.size();

    // Determine if pagination is required:
    boolean bPaginationRequired = (start!=null)&&(limit!=null);

    if (bPaginationRequired) {  

        // Do not forget to provide the total size of the data set
        DirectOptions.setOption("total", total);

        limit = Math.min(start+limit, total) );
        companyList = companyList.subList(start, limit );
        System.out.println("getCompanies method has returned page of " + start  + " - " + (limit-1) + "out of " + total + " CompanyDTO records");
    } else {            
        System.out.println("getCompanies method has returned entire list of " + companyList.size() + " CompanyDTO records");
    }
    return companyList;
}

Now, keep in mind that once your Java method is paginating, it does matter whether the user flippes pages or not: until you disable pagination of your store the start and limit options are sent along with a load request so you only get a page worth of data. You can control the size of the page with the pageSize, of course.

Adding the Pagination Toolbar to the View

When you add paging toolbar to the View make sure to bind it to the right store - the one you want to page. In the following example both view and paging toolbar are bound to example.CompanyStore. As a reminder, example.CompanyStore is the short id of the store, so both components refer to the same store instance:

Ext.define('Example.view.CompanyList', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.companylist'

  title: 'Companies',
  store: 'example.CompanyStore',
  minWidth: 400,
  minHeight:140,
  selModel: {
    allowDeselect: true
  },

  dockedItems: [{
    xtype: 'toolbar',
    dock: 'bottom',

    items: [
        {
            xtype:'pagingtoolbar',
            store: 'example.CompanyStore',
            displayInfo: true,
            displayMsg: 'Displaying companies {0} - {1} of {2}',
            emptyMsg: "No companies to show"
        }    
    ]

  }],
  columns: [{
    header: 'Id',
    dataIndex: 'id',
    flex: 1
  }, {
    header: 'Company Name',
    dataIndex: 'companyName',
    flex: 1,
    editor: {
        xtype: 'textfield',
        allowBlank: false
    }
  }]
});