paging

Ext JS 4: Updating Ext.ux.data.PagingStore

I am in the process of updating an Ext JS 3 application to use Ext JS 4. So far so good, until I got to one grid that uses Condor’s Ext.ux.data.PagingStore. I tried to get away with using the Ext.ux.data.PagingMemoryProxy, but it was not to be since I want to add and remove records from the store. I tried to find an updated version among the thread in the forum, but had no luck. Therefore, I tried my hand at updating Ext.ux.data.PagingStore for Ext JS 4.

The code for Ext.ux.data.PagingStore is at https://github.com/aghuddleston/Ext.ux.data.PagingStore. I have also included some unit tests, using Siesta as the testing tool. I’m just starting to integrate this into my application, so it’s not well tested yet… I’ll be updating the code as changes are needed.

The main difference from the previous version is that in Ext JS 4 is that “start”, “limit” and “page” are no longer set on the params in the load request, but are their own properties on the Ext.data.Operation config object. A request is only made to load data if the params or extraParams change from the previous load request. Otherwise, it will just page the data. Any proxy should be usable, but I have only tested “ajax” and “memory”. Samples of configuring the data store and loading data are in the comments in the code.

Helpful links:

Version Info:
Ext JS 4.1.1

ExtJS 4 – Remembering Paging Params

I’m using the Paging Toolbar for a grid in ExtJS 4.  I have  a search panel and when the user clicks “Search”, the store load is initiated.  I finally got the store to remember it’s parameters and load as I wanted which was:

  • When the search button is clicked, should be loading the first page
  • When the next or previous buttons is clicked on the paging toolbar, go to the previous or next page.
I finally got it work by setting the extraParams field and then instead of calling store.load, called store.loadPage(1) for when the search button is clicked.
Like this:
findUsers: function(searchCrit) {
	this.store.proxy.extraParams = searchCrit;
	this.store.loadPage(1);
}

where searchCrit is an object that has the name/value pairs that I use for the search criteria. This way everytime the user clicks “search” the extraParams is updated with the latest, and the first page is loaded.

ExtJS Paging Toolbar that can right justify

I wanted a paging toolbar that could be placed in right-side of the toolbar, allowing you to put your own buttons on the left-side. Since PagingToolbar.initComponent decides where the fill goes, I had to extend and override initComponent so that I had control over the fill. I also added my own param alignPagingRight that defaults to false. When it is set to true, it will put the paging control on the right side of the fill.


Ext.namespace("Ext.ux");
var T = Ext.Toolbar;
/**
 * @class Ext.ux.JustifyPagingToolbar
 * @extends Ext.PagingToolbar
 * <p>This just extends the standard ExtJS paging toolbar so that the paging 
 * parts of the toolbar can be aligned on the right side of the toolbar. The
 * code in initComponent is copied directly from Ext.PagingToolbar, but with 
 * some slight modifications and the addition of the alignPagingRight config
 * item</p>
 * @constructor
 * Create a new Ext.ux.JustifyPagingToolbar
 * @param {Object} config The config object
 * @xtype justifypagingtoolbar
 */
Ext.ux.JustifyPagingToolbar= Ext.extend(Ext.PagingToolbar, {

    /**
     * @cfg {Boolean} alignPagingRight
     * <tt>true</tt> to put the paging toolbar items after a fill item, and
	 * therefore on the right-side of the toolbar.  Will put the displayInfo
	 * text immediately after the paging toolbar items.  If this is false, the
	 * paging toolbar items and and user items will appear on the left-side.
     * Defaults to <tt>false</tt>.
     */
	alignPagingRight : false,
	
	initComponent : function() {
       var pagingItems = [this.first = new T.Button({
            tooltip: this.firstText,
            overflowText: this.firstText,
            iconCls: 'x-tbar-page-first',
            disabled: true,
            handler: this.moveFirst,
            scope: this
        }), this.prev = new T.Button({
            tooltip: this.prevText,
            overflowText: this.prevText,
            iconCls: 'x-tbar-page-prev',
            disabled: true,
            handler: this.movePrevious,
            scope: this
        }), '-', this.beforePageText,
        this.inputItem = new Ext.form.NumberField({
            cls: 'x-tbar-page-number',
            allowDecimals: false,
            allowNegative: false,
            enableKeyEvents: true,
            selectOnFocus: true,
            listeners: {
                scope: this,
                keydown: this.onPagingKeyDown,
                blur: this.onPagingBlur
            }
        }), this.afterTextItem = new T.TextItem({
            text: String.format(this.afterPageText, 1)
        }), '-', this.next = new T.Button({
            tooltip: this.nextText,
            overflowText: this.nextText,
            iconCls: 'x-tbar-page-next',
            disabled: true,
            handler: this.moveNext,
            scope: this
        }), this.last = new T.Button({
            tooltip: this.lastText,
            overflowText: this.lastText,
            iconCls: 'x-tbar-page-last',
            disabled: true,
            handler: this.moveLast,
            scope: this
        }), '-', this.refresh = new T.Button({
            tooltip: this.refreshText,
            overflowText: this.refreshText,
            iconCls: 'x-tbar-loading',
            handler: this.refresh,
            scope: this
        })];


        var userItems = this.items || this.buttons || [];
		
		/* override here */
		if (this.alignPagingRight) {
			userItems.push('->');
		}
		/* end override */
		
        if (this.prependButtons) {
            this.items = userItems.concat(pagingItems);
        }else{
            this.items = pagingItems.concat(userItems);
        }
        delete this.buttons;
        if(this.displayInfo){
			/* override here */
			if ( !this.alignPagingRight) {
				this.items.push('->');
			}
			/* end override */
            this.items.push(this.displayItem = new T.TextItem({}));
        }
        Ext.PagingToolbar.superclass.initComponent.call(this);
        this.addEvents(
            /**
             * @event change
             * Fires after the active page has been changed.
             * @param {Ext.PagingToolbar} this
             * @param {Object} pageData An object that has these properties:<ul>
             * <li><code>total</code> : Number <div class="sub-desc">The total number of records in the dataset as
             * returned by the server</div></li>
             * <li><code>activePage</code> : Number <div class="sub-desc">The current page number</div></li>
             * <li><code>pages</code> : Number <div class="sub-desc">The total number of pages (calculated from
             * the total number of records in the dataset as returned by the server and the current {@link #pageSize})</div></li>
             * </ul>
             */
            'change',
            /**
             * @event beforechange
             * Fires just before the active page is changed.
             * Return false to prevent the active page from being changed.
             * @param {Ext.PagingToolbar} this
             * @param {Object} params An object hash of the parameters which the PagingToolbar will send when
             * loading the required page. This will contain:<ul>
             * <li><code>start</code> : Number <div class="sub-desc">The starting row number for the next page of records to
             * be retrieved from the server</div></li>
             * <li><code>limit</code> : Number <div class="sub-desc">The number of records to be retrieved from the server</div></li>
             * </ul>
             * <p>(note: the names of the <b>start</b> and <b>limit</b> properties are determined
             * by the store's {@link Ext.data.Store#paramNames paramNames} property.)</p>
             * <p>Parameters may be added as required in the event handler.</p>
             */
            'beforechange'
        );
        this.on('afterlayout', this.onFirstLayout, this, {single: true});
        this.cursor = 0;
        this.bindStore(this.store);
	}

});

Ext.reg('justifypagingtoolbar', Ext.ux.JustifyPagingToolbar);