X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6746dc89c47ed01b165cc1152533605f97eb8e8d..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/src/toolbar/Paging.js diff --git a/src/toolbar/Paging.js b/src/toolbar/Paging.js index a4804b10..2f9e7dce 100644 --- a/src/toolbar/Paging.js +++ b/src/toolbar/Paging.js @@ -13,110 +13,107 @@ If you are unsure which license is appropriate for your use, please contact the */ /** - * @class Ext.toolbar.Paging - * @extends Ext.toolbar.Toolbar - *

As the amount of records increases, the time required for the browser to render - * them increases. Paging is used to reduce the amount of data exchanged with the client. - * Note: if there are more records/rows than can be viewed in the available screen area, vertical - * scrollbars will be added.

- *

Paging is typically handled on the server side (see exception below). The client sends - * parameters to the server side, which the server needs to interpret and then respond with the - * appropriate data.

- *

Ext.toolbar.Paging is a specialized toolbar that is bound to a {@link Ext.data.Store} - * and provides automatic paging control. This Component {@link Ext.data.Store#load load}s blocks - * of data into the {@link #store} by passing {@link Ext.data.Store#paramNames paramNames} used for - * paging criteria.

+ * As the number of records increases, the time required for the browser to render them increases. Paging is used to + * reduce the amount of data exchanged with the client. Note: if there are more records/rows than can be viewed in the + * available screen area, vertical scrollbars will be added. + * + * Paging is typically handled on the server side (see exception below). The client sends parameters to the server side, + * which the server needs to interpret and then respond with the appropriate data. + * + * Ext.toolbar.Paging is a specialized toolbar that is bound to a {@link Ext.data.Store} and provides automatic + * paging control. This Component {@link Ext.data.Store#load load}s blocks of data into the {@link #store} by passing + * parameters used for paging criteria. * * {@img Ext.toolbar.Paging/Ext.toolbar.Paging.png Ext.toolbar.Paging component} * - *

PagingToolbar is typically used as one of the Grid's toolbars:

- *

- *    var itemsPerPage = 2;   // set the number of items you want per page
- *    
- *    var store = Ext.create('Ext.data.Store', {
- *        id:'simpsonsStore',
- *        autoLoad: false,
- *        fields:['name', 'email', 'phone'],
- *        pageSize: itemsPerPage, // items per page
- *        proxy: {
- *            type: 'ajax',
- *            url: 'pagingstore.js',  // url that will load data with respect to start and limit params
- *            reader: {
- *                type: 'json',
- *                root: 'items',
- *                totalProperty: 'total'
- *            }
- *        }
- *    });
- *    
- *    // specify segment of data you want to load using params
- *    store.load({
- *        params:{
- *            start:0,    
- *            limit: itemsPerPage
- *        }
- *    });
- *    
- *    Ext.create('Ext.grid.Panel', {
- *        title: 'Simpsons',
- *        store: store,
- *        columns: [
- *            {header: 'Name',  dataIndex: 'name'},
- *            {header: 'Email', dataIndex: 'email', flex:1},
- *            {header: 'Phone', dataIndex: 'phone'}
- *        ],
- *        width: 400,
- *        height: 125,
- *        dockedItems: [{
- *            xtype: 'pagingtoolbar',
- *            store: store,   // same store GridPanel is using
- *            dock: 'bottom',
- *            displayInfo: true
- *        }],
- *        renderTo: Ext.getBody()
- *    });
- * 
+ * Paging Toolbar is typically used as one of the Grid's toolbars: * - *

To use paging, pass the paging requirements to the server when the store is first loaded.

- *

-store.load({
-    params: {
-        // specify params for the first page load if using paging
-        start: 0,          
-        limit: myPageSize,
-        // other params
-        foo:   'bar'
-    }
-});
- * 
- * - *

If using {@link Ext.data.Store#autoLoad store's autoLoad} configuration:

- *

-var myStore = new Ext.data.Store({
-    {@link Ext.data.Store#autoLoad autoLoad}: {start: 0, limit: 25},
-    ...
-});
- * 
- * - *

The packet sent back from the server would have this form:

- *

-{
-    "success": true,
-    "results": 2000, 
-    "rows": [ // *Note: this must be an Array 
-        { "id":  1, "name": "Bill", "occupation": "Gardener" },
-        { "id":  2, "name":  "Ben", "occupation": "Horticulturalist" },
-        ...
-        { "id": 25, "name":  "Sue", "occupation": "Botanist" }
-    ]
-}
- * 
- *

Paging with Local Data

- *

Paging can also be accomplished with local data using extensions:

- *
+ * @example + * var itemsPerPage = 2; // set the number of items you want per page + * + * var store = Ext.create('Ext.data.Store', { + * id:'simpsonsStore', + * autoLoad: false, + * fields:['name', 'email', 'phone'], + * pageSize: itemsPerPage, // items per page + * proxy: { + * type: 'ajax', + * url: 'pagingstore.js', // url that will load data with respect to start and limit params + * reader: { + * type: 'json', + * root: 'items', + * totalProperty: 'total' + * } + * } + * }); + * + * // specify segment of data you want to load using params + * store.load({ + * params:{ + * start:0, + * limit: itemsPerPage + * } + * }); + * + * Ext.create('Ext.grid.Panel', { + * title: 'Simpsons', + * store: store, + * columns: [ + * { header: 'Name', dataIndex: 'name' }, + * { header: 'Email', dataIndex: 'email', flex: 1 }, + * { header: 'Phone', dataIndex: 'phone' } + * ], + * width: 400, + * height: 125, + * dockedItems: [{ + * xtype: 'pagingtoolbar', + * store: store, // same store GridPanel is using + * dock: 'bottom', + * displayInfo: true + * }], + * renderTo: Ext.getBody() + * }); + * + * To use paging, pass the paging requirements to the server when the store is first loaded. + * + * store.load({ + * params: { + * // specify params for the first page load if using paging + * start: 0, + * limit: myPageSize, + * // other params + * foo: 'bar' + * } + * }); + * + * If using {@link Ext.data.Store#autoLoad store's autoLoad} configuration: + * + * var myStore = Ext.create('Ext.data.Store', { + * {@link Ext.data.Store#autoLoad autoLoad}: {start: 0, limit: 25}, + * ... + * }); + * + * The packet sent back from the server would have this form: + * + * { + * "success": true, + * "results": 2000, + * "rows": [ // ***Note:** this must be an Array + * { "id": 1, "name": "Bill", "occupation": "Gardener" }, + * { "id": 2, "name": "Ben", "occupation": "Horticulturalist" }, + * ... + * { "id": 25, "name": "Sue", "occupation": "Botanist" } + * ] + * } + * + * ## Paging with Local Data + * + * Paging can also be accomplished with local data using extensions: + * + * - [Ext.ux.data.PagingStore][1] + * - Paging Memory Proxy (examples/ux/PagingMemoryProxy.js) + * + * [1]: http://sencha.com/forum/showthread.php?t=71532 */ Ext.define('Ext.toolbar.Paging', { extend: 'Ext.toolbar.Toolbar', @@ -124,89 +121,98 @@ Ext.define('Ext.toolbar.Paging', { alternateClassName: 'Ext.PagingToolbar', requires: ['Ext.toolbar.TextItem', 'Ext.form.field.Number'], /** - * @cfg {Ext.data.Store} store - * The {@link Ext.data.Store} the paging toolbar should use as its data source (required). + * @cfg {Ext.data.Store} store (required) + * The {@link Ext.data.Store} the paging toolbar should use as its data source. */ + /** * @cfg {Boolean} displayInfo - * true to display the displayMsg (defaults to false) + * true to display the displayMsg */ displayInfo: false, + /** * @cfg {Boolean} prependButtons - * true to insert any configured items before the paging buttons. - * Defaults to false. + * true to insert any configured items _before_ the paging buttons. */ prependButtons: false, + /** * @cfg {String} displayMsg - * The paging status message to display (defaults to 'Displaying {0} - {1} of {2}'). - * Note that this string is formatted using the braced numbers {0}-{2} as tokens - * that are replaced by the values for start, end and total respectively. These tokens should - * be preserved when overriding this string if showing those values is desired. + * The paging status message to display. Note that this string is + * formatted using the braced numbers {0}-{2} as tokens that are replaced by the values for start, end and total + * respectively. These tokens should be preserved when overriding this string if showing those values is desired. */ displayMsg : 'Displaying {0} - {1} of {2}', + /** * @cfg {String} emptyMsg - * The message to display when no records are found (defaults to 'No data to display') + * The message to display when no records are found. */ emptyMsg : 'No data to display', + /** * @cfg {String} beforePageText - * The text displayed before the input item (defaults to 'Page'). + * The text displayed before the input item. */ beforePageText : 'Page', + /** * @cfg {String} afterPageText - * Customizable piece of the default paging text (defaults to 'of {0}'). Note that - * this string is formatted using {0} as a token that is replaced by the number of - * total pages. This token should be preserved when overriding this string if showing the - * total page count is desired. + * Customizable piece of the default paging text. Note that this string is formatted using + * {0} as a token that is replaced by the number of total pages. This token should be preserved when overriding this + * string if showing the total page count is desired. */ afterPageText : 'of {0}', + /** * @cfg {String} firstText - * The quicktip text displayed for the first page button (defaults to 'First Page'). - * Note: quick tips must be initialized for the quicktip to show. + * The quicktip text displayed for the first page button. + * **Note**: quick tips must be initialized for the quicktip to show. */ firstText : 'First Page', + /** * @cfg {String} prevText - * The quicktip text displayed for the previous page button (defaults to 'Previous Page'). - * Note: quick tips must be initialized for the quicktip to show. + * The quicktip text displayed for the previous page button. + * **Note**: quick tips must be initialized for the quicktip to show. */ prevText : 'Previous Page', + /** * @cfg {String} nextText - * The quicktip text displayed for the next page button (defaults to 'Next Page'). - * Note: quick tips must be initialized for the quicktip to show. + * The quicktip text displayed for the next page button. + * **Note**: quick tips must be initialized for the quicktip to show. */ nextText : 'Next Page', + /** * @cfg {String} lastText - * The quicktip text displayed for the last page button (defaults to 'Last Page'). - * Note: quick tips must be initialized for the quicktip to show. + * The quicktip text displayed for the last page button. + * **Note**: quick tips must be initialized for the quicktip to show. */ lastText : 'Last Page', + /** * @cfg {String} refreshText - * The quicktip text displayed for the Refresh button (defaults to 'Refresh'). - * Note: quick tips must be initialized for the quicktip to show. + * The quicktip text displayed for the Refresh button. + * **Note**: quick tips must be initialized for the quicktip to show. */ refreshText : 'Refresh', + /** * @cfg {Number} inputItemWidth - * The width in pixels of the input field used to display and change the current page number (defaults to 30). + * The width in pixels of the input field used to display and change the current page number. */ inputItemWidth : 30, - + /** * Gets the standard paging items in the toolbar * @private */ getPagingItems: function() { var me = this; - + return [{ itemId: 'first', tooltip: me.firstText, @@ -282,49 +288,62 @@ Ext.define('Ext.toolbar.Paging', { var me = this, pagingItems = me.getPagingItems(), userItems = me.items || me.buttons || []; - + if (me.prependButtons) { me.items = userItems.concat(pagingItems); } else { me.items = pagingItems.concat(userItems); } delete me.buttons; - + if (me.displayInfo) { me.items.push('->'); me.items.push({xtype: 'tbtext', itemId: 'displayItem'}); } - + me.callParent(); - + me.addEvents( /** * @event change * Fires after the active page has been changed. * @param {Ext.toolbar.Paging} this - * @param {Object} pageData An object that has these properties: + * @param {Object} pageData An object that has these properties: + * + * - `total` : Number + * + * The total number of records in the dataset as returned by the server + * + * - `currentPage` : Number + * + * The current page number + * + * - `pageCount` : Number + * + * The total number of pages (calculated from the total number of records in the dataset as returned by the + * server and the current {@link Ext.data.Store#pageSize pageSize}) + * + * - `toRecord` : Number + * + * The starting record index for the current page + * + * - `fromRecord` : Number + * + * The ending record index for the current page */ 'change', + /** * @event beforechange - * Fires just before the active page is changed. - * Return false to prevent the active page from being changed. + * Fires just before the active page is changed. Return false to prevent the active page from being changed. * @param {Ext.toolbar.Paging} this - * @param {Number} page The page number that will be loaded on change + * @param {Number} page The page number that will be loaded on change */ 'beforechange' ); me.on('afterlayout', me.onLoad, me, {single: true}); - me.bindStore(me.store, true); + me.bindStore(me.store || 'ext-empty-store', true); }, // private updateInfo : function(){ @@ -358,7 +377,7 @@ Ext.define('Ext.toolbar.Paging', { currPage, pageCount, afterText; - + if (!me.rendered) { return; } @@ -383,14 +402,14 @@ Ext.define('Ext.toolbar.Paging', { getPageData : function(){ var store = this.store, totalCount = store.getTotalCount(); - + return { total : totalCount, currentPage : store.currentPage, pageCount: Math.ceil(totalCount / store.pageSize), fromRecord: ((store.currentPage - 1) * store.pageSize) + 1, toRecord: Math.min(store.currentPage * store.pageSize, totalCount) - + }; }, @@ -406,7 +425,7 @@ Ext.define('Ext.toolbar.Paging', { readPageFromInput : function(pageData){ var v = this.child('#inputItem').getValue(), pageNum = parseInt(v, 10); - + if (!v || isNaN(pageNum)) { this.child('#inputItem').setValue(pageData.currentPage); return false; @@ -489,7 +508,7 @@ Ext.define('Ext.toolbar.Paging', { movePrevious : function(){ var me = this, prev = me.store.currentPage - 1; - + if (prev > 0) { if (me.fireEvent('beforechange', me, prev) !== false) { me.store.previousPage(); @@ -504,7 +523,7 @@ Ext.define('Ext.toolbar.Paging', { var me = this, total = me.getPageData().pageCount, next = me.store.currentPage + 1; - + if (next <= total) { if (me.fireEvent('beforechange', me, next) !== false) { me.store.nextPage(); @@ -516,9 +535,9 @@ Ext.define('Ext.toolbar.Paging', { * Move to the last page, has the same effect as clicking the 'last' button. */ moveLast : function(){ - var me = this, + var me = this, last = me.getPageData().pageCount; - + if (me.fireEvent('beforechange', me, last) !== false) { me.store.loadPage(last); } @@ -530,7 +549,7 @@ Ext.define('Ext.toolbar.Paging', { doRefresh : function(){ var me = this, current = me.store.currentPage; - + if (me.fireEvent('beforechange', me, current) !== false) { me.store.loadPage(current); } @@ -538,15 +557,15 @@ Ext.define('Ext.toolbar.Paging', { /** * Binds the paging toolbar to the specified {@link Ext.data.Store} - * @param {Store} store The store to bind to this toolbar + * @param {Ext.data.Store} store The store to bind to this toolbar * @param {Boolean} initial (Optional) true to not remove listeners */ bindStore : function(store, initial){ var me = this; - + if (!initial && me.store) { if(store !== me.store && me.store.autoDestroy){ - me.store.destroy(); + me.store.destroyStore(); }else{ me.store.un('beforeload', me.beforeLoad, me); me.store.un('load', me.onLoad, me); @@ -569,7 +588,7 @@ Ext.define('Ext.toolbar.Paging', { }, /** - * Unbinds the paging toolbar from the specified {@link Ext.data.Store} (deprecated) + * Unbinds the paging toolbar from the specified {@link Ext.data.Store} **(deprecated)** * @param {Ext.data.Store} store The data store to unbind */ unbind : function(store){ @@ -577,7 +596,7 @@ Ext.define('Ext.toolbar.Paging', { }, /** - * Binds the paging toolbar to the specified {@link Ext.data.Store} (deprecated) + * Binds the paging toolbar to the specified {@link Ext.data.Store} **(deprecated)** * @param {Ext.data.Store} store The data store to bind */ bind : function(store){