1 /** 2 * Originally from: http://extjs.com/forum/showthread.php?t=38809 3 */ 4 5 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, 6 { 7 autoLoad: false, 8 mode: 'buttons', 9 includeTextbox: true, 10 pageSize: 20, 11 displayMsg : 'Displaying {0} - {1} of {2}', 12 emptyMsg : 'No data to display', 13 beforePageText : "Page", 14 afterPageText : "of {0}", 15 firstText : "First Page", 16 prevText : "Previous Page", 17 nextText : "Next Page", 18 lastText : "Last Page", 19 refreshText : "Refresh", 20 paramNames : {start: 'start', limit: 'limit'}, 21 22 initComponent: function() 23 { 24 Ext.PagingToolbar.superclass.initComponent.call(this); 25 this.current = 0; 26 this.bind(this.store); 27 this.addEvents('beforepagechange', 'pagechange'); 28 }, 29 30 onRender: function(ct, position) 31 { 32 Ext.PagingToolbar.superclass.onRender.call(this, ct, position); 33 34 this.first = this.addButton( 35 { 36 tooltip: this.firstText, 37 iconCls: "x-tbar-page-first", 38 disabled: true, 39 scope: this, 40 handler: this.moveFirst 41 } 42 ); 43 this.prev = this.addButton( 44 { 45 tooltip: this.prevText, 46 iconCls: "x-tbar-page-prev", 47 disabled: true, 48 scope: this, 49 handler: this.movePrevious 50 } 51 ); 52 this.setupTextBox(); 53 this.addSeparator(); 54 this.next = this.addButton( 55 { 56 tooltip: this.nextText, 57 iconCls: "x-tbar-page-next", 58 disabled: true, 59 scope: this, 60 handler: this.moveNext 61 } 62 ); 63 this.last = this.addButton( 64 { 65 tooltip: this.lastText, 66 iconCls: "x-tbar-page-last", 67 disabled: true, 68 scope: this, 69 handler: this.moveLast 70 } 71 ); 72 73 this.addSeparator(); 74 this.loading = this.addButton( 75 { 76 tooltip: this.refreshText, 77 iconCls: "x-tbar-loading", 78 scope: this, 79 handler: this.refresh 80 } 81 ); 82 83 if (this.displayInfo) 84 this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'}); 85 86 if (this.autoLoad) 87 this.doLoad(0); 88 else if (this.dsLoaded) 89 this.onLoad.apply(this, this.dsLoaded); 90 }, 91 92 getPageSize: function() 93 { 94 return this.pageSize; 95 }, 96 97 setPageSize: function(size) 98 { 99 this.pageSize = size; 100 this.moveFirst(); 101 }, 102 103 getActivePage: function() 104 { 105 return this.current; 106 }, 107 108 setActivePage: function(page) 109 { 110 if (!isNaN(page)) 111 { 112 if (page >= 0 && page <= this.getLastPage()) 113 { 114 this.doLoad(page); 115 return true; 116 } 117 } 118 return false; 119 }, 120 121 refresh: function() 122 { 123 this.doLoad(this.current); 124 }, 125 126 moveFirst: function() 127 { 128 return this.setActivePage(0); 129 }, 130 131 movePrevious: function() 132 { 133 return this.setActivePage(this.current - 1); 134 }, 135 136 moveNext: function() 137 { 138 return this.setActivePage(this.current + 1); 139 }, 140 141 moveLast: function() 142 { 143 return this.setActivePage(this.getLastPage()); 144 }, 145 146 unbind: function(store) 147 { 148 store = Ext.StoreMgr.lookup(store); 149 store.un("beforeload", this.beforeLoad, this); 150 store.un("load", this.onLoad, this); 151 store.un("loadexception", this.onLoadError, this); 152 this.store = undefined; 153 }, 154 155 bind : function(store) 156 { 157 store = Ext.StoreMgr.lookup(store); 158 store.on("beforeload", this.beforeLoad, this); 159 store.on("load", this.onLoad, this); 160 store.on("loadexception", this.onLoadError, this); 161 this.store = store; 162 }, 163 164 //private 165 setupTextBox: function() 166 { 167 if (this.includeTextbox) 168 { 169 this.addSeparator(); 170 this.add(this.beforePageText); 171 this.field = Ext.get(this.addDom( 172 { 173 tag: "input", 174 type: "text", 175 size: "3", 176 value: "1", 177 cls: "x-tbar-page-number" 178 }).el); 179 this.field.on("keydown", this.onPagingKeydown, this); 180 this.field.on("focus", function() 181 { 182 this.dom.select(); 183 } 184 ); 185 this.afterTextEl = this.addText(String.format(this.afterPageText, 1)); 186 this.field.setHeight(18); 187 } 188 }, 189 190 //private 191 updateInfo: function() 192 { 193 if (this.displayEl) 194 { 195 var count = this.store.getCount(); 196 var disp = (this.current * this.pageSize) + 1; 197 var msg = count == 0 ? this.emptyMsg : String.format(this.displayMsg, disp, disp + count - 1, this.store.getTotalCount()); 198 this.displayEl.update(msg); 199 } 200 }, 201 202 //private 203 getPageData: function() 204 { 205 var total = this.store.getTotalCount(); 206 return { 207 total: total, 208 pages: total < this.pageSize ? 1 : Math.ceil(total / this.pageSize) 209 }; 210 }, 211 212 //private 213 onLoad: function(store, r, o) 214 { 215 if (!this.rendered) 216 { 217 this.dsLoaded = [store, r, o]; 218 return; 219 } 220 221 var p = o.params; 222 this.current = p ? Math.floor(p[this.paramNames.start] / p[this.paramNames.limit]) : 0; 223 this.fireEvent('pagechange', this, this.current) 224 var pages = this.getPageData().pages; 225 if (this.includeTextbox) 226 { 227 this.afterTextEl.el.innerHTML = String.format(this.afterPageText, pages); 228 this.field.dom.value = this.current + 1; 229 } 230 231 this.first.setDisabled(this.current == 0); 232 this.prev.setDisabled(this.current == 0); 233 this.next.setDisabled(this.current == pages - 1); 234 this.last.setDisabled(this.current == pages - 1); 235 this.loading.enable(); 236 this.updateInfo(); 237 }, 238 239 //private 240 onLoadError: function() 241 { 242 if (!this.rendered) 243 return; 244 245 this.loading.enable(); 246 }, 247 248 //private 249 beforeLoad: function() 250 { 251 if (this.rendered && this.loading) 252 this.loading.disable(); 253 }, 254 255 //private 256 doLoad: function(start) 257 { 258 if (this.fireEvent('beforepagechange', this, start) !== false) 259 { 260 var o = {}, pn = this.paramNames; 261 o[pn.start] = start * this.pageSize; 262 o[pn.limit] = this.pageSize; 263 this.store.load({params:o}); 264 } 265 else 266 { 267 if (this.useTextBox) 268 this.field.dom.value = this.current + 1; 269 } 270 }, 271 272 //private 273 readPage : function() 274 { 275 var v = this.field.dom.value, pageNum; 276 if (!v || isNaN(pageNum = parseInt(v, 10))) 277 { 278 this.field.dom.value = this.current + 1; 279 return false; 280 } 281 return pageNum; 282 }, 283 284 //private 285 onPagingKeydown: function(e) 286 { 287 var k = e.getKey(), pages = this.getPageData().pages, pageNum; 288 if (k == e.RETURN) 289 { 290 e.stopEvent(); 291 if (pageNum = this.readPage()) 292 { 293 pageNum = Math.min(Math.max(1, pageNum), pages) - 1; 294 this.loadOrSet(pageNum); 295 } 296 } 297 else if (k == e.HOME || k == e.END) 298 { 299 e.stopEvent(); 300 pageNum = k == e.HOME ? 1 : pages; 301 this.field.dom.value = pageNum; 302 this.loadOrSet(pageNum - 1); 303 } 304 else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN) 305 { 306 e.stopEvent(); 307 if (pageNum = this.readPage()) 308 { 309 var increment = e.shiftKey ? 10 : 1; 310 if (k == e.DOWN || k == e.PAGEDOWN) 311 increment *= -1; 312 313 pageNum += increment; 314 if (pageNum > pages) 315 pageNum = pages; 316 else if (pageNum < 1) 317 pageNum = 1; 318 319 this.field.dom.value = pageNum; 320 this.loadOrSet(pageNum - 1); 321 } 322 } 323 }, 324 325 //private 326 loadOrSet: function(num) 327 { 328 this.doLoad(num); 329 }, 330 331 //private 332 getLastPage: function() 333 { 334 return this.getPageData().pages - 1; 335 } 336 } 337 ); 338 339 Ext.namespace('Ext.ux'); 340 341 Ext.ux.PageSizePlugin = function() { 342 Ext.ux.PageSizePlugin.superclass.constructor.call(this, { 343 store: new Ext.data.SimpleStore({ 344 fields: ['text', 'value'], 345 data: [['10', 10], ['20', 20], ['30', 30], ['50', 50], ['100', 100],['200','200']] 346 }), 347 mode: 'local', 348 displayField: 'text', 349 valueField: 'value', 350 triggerAction: 'all', 351 width: 45, 352 regex: /^\d+$/, 353 regexText: 'Please enter numerals only.', 354 editable: true, 355 forceSelection: false 356 }); 357 }; 358 359 Ext.extend(Ext.ux.PageSizePlugin, Ext.form.ComboBox, { 360 init: function(paging) { 361 paging.on('render', this.onInitView, this); 362 }, 363 364 onInitView: function(paging) { 365 paging.add('-',this,'Items per page','-'); 366 this.setValue(paging.pageSize); 367 this.on('select', this.onPageSizeChanged, paging); 368 this.on('change', this.onPageSizeChanged, paging); 369 }, 370 371 onPageSizeChanged: function(combo) { 372 if (combo.isValid()) { 373 this.pageSize = parseInt(combo.getValue()); 374 this.doLoad(0); 375 } 376 } 377 }); 378