- Timestamp:
- Jan 23, 2014, 9:24:23 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/UserAdvManager/trunk/admin/template/js/jquery.tablesorter.pager.js
r6399 r26933 1 (function($) { 2 $.extend({ 3 tablesorterPager: new function() { 4 5 function updatePageDisplay(c) { 6 var s = $(c.cssPageDisplay,c.container).val((c.page+1) + c.seperator + c.totalPages); 7 } 8 9 function setPageSize(table,size) { 10 var c = table.config; 11 c.size = size; 12 c.totalPages = Math.ceil(c.totalRows / c.size); 13 c.pagerPositionSet = false; 14 moveToPage(table); 15 fixPosition(table); 16 } 17 18 function fixPosition(table) { 19 var c = table.config; 20 if(!c.pagerPositionSet && c.positionFixed) { 21 var c = table.config, o = $(table); 22 if(o.offset) { 23 c.container.css({ 24 top: o.offset().top + o.height() + 'px', 25 position: 'absolute' 1 /*! 2 * tablesorter pager plugin 3 * updated 12/16/2013 (v2.14.5) 4 */ 5 /*jshint browser:true, jquery:true, unused:false */ 6 ;(function($) { 7 "use strict"; 8 /*jshint supernew:true */ 9 var ts = $.tablesorter; 10 11 $.extend({ tablesorterPager: new function() { 12 13 this.defaults = { 14 // target the pager markup 15 container: null, 16 17 // use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}" 18 // where {page} is replaced by the page number, {size} is replaced by the number of records to show, 19 // {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds 20 // the filterList to the url into an "fcol" array. 21 // So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url 22 // and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url 23 ajaxUrl: null, 24 25 // modify the url after all processing has been applied 26 customAjaxUrl: function(table, url) { return url; }, 27 28 // modify the $.ajax object to allow complete control over your ajax requests 29 ajaxObject: { 30 dataType: 'json' 31 }, 32 33 // set this to false if you want to block ajax loading on init 34 processAjaxOnInit: true, 35 36 // process ajax so that the following information is returned: 37 // [ total_rows (number), rows (array of arrays), headers (array; optional) ] 38 // example: 39 // [ 40 // 100, // total rows 41 // [ 42 // [ "row1cell1", "row1cell2", ... "row1cellN" ], 43 // [ "row2cell1", "row2cell2", ... "row2cellN" ], 44 // ... 45 // [ "rowNcell1", "rowNcell2", ... "rowNcellN" ] 46 // ], 47 // [ "header1", "header2", ... "headerN" ] // optional 48 // ] 49 ajaxProcessing: function(ajax){ return [ 0, [], null ]; }, 50 51 // output default: '{page}/{totalPages}' 52 // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows} 53 output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}' 54 55 // apply disabled classname to the pager arrows when the rows at either extreme is visible 56 updateArrows: true, 57 58 // starting page of the pager (zero based index) 59 page: 0, 60 61 // Number of visible rows 62 size: 10, 63 64 // Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js) 65 savePages: true, 66 67 // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty 68 // table row set to a height to compensate; default is false 69 fixedHeight: false, 70 71 // count child rows towards the set page size? (set true if it is a visible table row within the pager) 72 // if true, child row(s) may not appear to be attached to its parent row, may be split across pages or 73 // may distort the table if rowspan or cellspans are included. 74 countChildRows: false, 75 76 // remove rows from the table to speed up the sort of large tables. 77 // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled. 78 removeRows: false, // removing rows in larger tables speeds up the sort 79 80 // css class names of pager arrows 81 cssFirst: '.first', // go to first page arrow 82 cssPrev: '.prev', // previous page arrow 83 cssNext: '.next', // next page arrow 84 cssLast: '.last', // go to last page arrow 85 cssGoto: '.gotoPage', // go to page selector - select dropdown that sets the current page 86 cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed 87 cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option 88 cssErrorRow: 'tablesorter-errorRow', // error information row 89 90 // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page) 91 cssDisabled: 'disabled', // Note there is no period "." in front of this class name 92 93 // stuff not set by the user 94 totalRows: 0, 95 totalPages: 0, 96 filteredRows: 0, 97 filteredPages: 0, 98 ajaxCounter: 0, 99 currentFilters: [], 100 startRow: 0, 101 endRow: 0, 102 $size: null, 103 last: {} 104 105 }; 106 107 var $this = this, 108 109 // hide arrows at extremes 110 pagerArrows = function(p, disable) { 111 var a = 'addClass', 112 r = 'removeClass', 113 d = p.cssDisabled, 114 dis = !!disable, 115 tp = Math.min( p.totalPages, p.filteredPages ); 116 if ( p.updateArrows ) { 117 p.$container.find(p.cssFirst + ',' + p.cssPrev)[ ( dis || p.page === 0 ) ? a : r ](d); 118 p.$container.find(p.cssNext + ',' + p.cssLast)[ ( dis || p.page === tp - 1 || p.totalPages === 0 ) ? a : r ](d); 119 } 120 }, 121 122 updatePageDisplay = function(table, p, flag) { 123 var i, pg, s, out, 124 c = table.config, 125 f = c.$table.hasClass('hasFilters') && !p.ajaxUrl, 126 t = (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered') + ',' + c.selectorRemove + 127 (p.countChildRows ? '' : ',.' + c.cssChildRow), 128 sz = p.size || 10; // don't allow dividing by zero 129 p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method 130 p.filteredRows = (f) ? c.$tbodies.eq(0).children('tr').not('.' + t ).length : p.totalRows; 131 p.filteredPages = (f) ? Math.ceil( p.filteredRows / sz ) || 1 : p.totalPages; 132 if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) { 133 t = (p.size * p.page > p.filteredRows); 134 p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1); 135 p.page = (t) ? 0 : p.page; 136 p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) ); 137 out = p.$container.find(p.cssPageDisplay); 138 // form the output string (can now get a new output string from the server) 139 s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || p.output : p.output ) 140 // {page} = one-based index; {page+#} = zero based index +/- value 141 .replace(/\{page([\-+]\d+)?\}/gi, function(m,n){ 142 return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0; 143 }) 144 // {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object) 145 .replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){ 146 var str = m.replace(/[{}\s]/g,''), 147 extra = str.split(':'), 148 data = p.ajaxData, 149 // return zero for default page/row numbers 150 deflt = /(rows?|pages?)$/i.test(str) ? 0 : ''; 151 return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt; 152 }); 153 if (out.length) { 154 out[ (out[0].tagName === 'INPUT') ? 'val' : 'html' ](s); 155 if ( p.$goto.length ) { 156 t = ''; 157 pg = Math.min( p.totalPages, p.filteredPages ); 158 for ( i = 1; i <= pg; i++ ) { 159 t += '<option>' + i + '</option>'; 160 } 161 p.$goto.html(t).val( p.page + 1 ); 162 } 163 } 164 } 165 pagerArrows(p); 166 if (p.initialized && flag !== false) { 167 c.$table.trigger('pagerComplete', p); 168 // save pager info to storage 169 if (p.savePages && ts.storage) { 170 ts.storage(table, 'tablesorter-pager', { 171 page : p.page, 172 size : p.size 173 }); 174 } 175 } 176 }, 177 178 fixHeight = function(table, p) { 179 var d, h, 180 c = table.config, 181 $b = c.$tbodies.eq(0); 182 if (p.fixedHeight) { 183 $b.find('tr.pagerSavedHeightSpacer').remove(); 184 h = $.data(table, 'pagerSavedHeight'); 185 if (h) { 186 d = h - $b.height(); 187 if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) { 188 $b.append('<tr class="pagerSavedHeightSpacer ' + c.selectorRemove.replace(/(tr)?\./g,'') + '" style="height:' + d + 'px;"></tr>'); 189 } 190 } 191 } 192 }, 193 194 changeHeight = function(table, p) { 195 var $b = table.config.$tbodies.eq(0); 196 $b.find('tr.pagerSavedHeightSpacer').remove(); 197 $.data(table, 'pagerSavedHeight', $b.height()); 198 fixHeight(table, p); 199 $.data(table, 'pagerLastSize', p.size); 200 }, 201 202 hideRows = function(table, p){ 203 if (!p.ajaxUrl) { 204 var i, 205 c = table.config, 206 rows = c.$tbodies.eq(0).children(), 207 l = rows.length, 208 s = ( p.page * p.size ), 209 e = s + p.size, 210 f = c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered', 211 j = 0; // size counter 212 for ( i = 0; i < l; i++ ){ 213 if ( !rows[i].className.match(f) ) { 214 rows[i].style.display = ( j >= s && j < e ) ? '' : 'none'; 215 // don't count child rows 216 j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.slice(1)) && !p.countChildRows ? 0 : 1; 217 } 218 } 219 } 220 }, 221 222 hideRowsSetup = function(table, p){ 223 p.size = parseInt( p.$size.val(), 10 ) || p.size; 224 $.data(table, 'pagerLastSize', p.size); 225 pagerArrows(p); 226 if ( !p.removeRows ) { 227 hideRows(table, p); 228 $(table).bind('sortEnd.pager filterEnd.pager', function(){ 229 hideRows(table, p); 230 }); 231 } 232 }, 233 234 renderAjax = function(data, table, p, xhr, exception){ 235 // process data 236 if ( typeof(p.ajaxProcessing) === "function" ) { 237 // ajaxProcessing result: [ total, rows, headers ] 238 var i, j, hsh, $f, $sh, t, th, d, l, $err, rr_count, 239 c = table.config, 240 $t = c.$table, 241 tds = '', 242 result = p.ajaxProcessing(data, table) || [ 0, [] ], 243 hl = $t.find('thead th').length; 244 245 $t.find('thead tr.' + p.cssErrorRow).remove(); // Clean up any previous error. 246 247 if ( exception ) { 248 if (c.debug) { 249 ts.log('Ajax Error', xhr, exception); 250 } 251 $err = $('<tr class="' + p.cssErrorRow + '"><td style="text-align:center;" colspan="' + hl + '">' + ( 252 xhr.status === 0 ? 'Not connected, verify Network' : 253 xhr.status === 404 ? 'Requested page not found [404]' : 254 xhr.status === 500 ? 'Internal Server Error [500]' : 255 exception === 'parsererror' ? 'Requested JSON parse failed' : 256 exception === 'timeout' ? 'Time out error' : 257 exception === 'abort' ? 'Ajax Request aborted' : 258 'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' ) + '</td></tr>') 259 .click(function(){ 260 $(this).remove(); 261 }) 262 // add error row to thead instead of tbody, or clicking on the header will result in a parser error 263 .appendTo( $t.find('thead:first') ); 264 c.$tbodies.eq(0).empty(); 265 } else { 266 // process ajax object 267 if (!$.isArray(result)) { 268 p.ajaxData = result; 269 p.totalRows = result.total; 270 th = result.headers; 271 d = result.rows; 272 } else { 273 // allow [ total, rows, headers ] or [ rows, total, headers ] 274 t = isNaN(result[0]) && !isNaN(result[1]); 275 //ensure a zero returned row count doesn't fail the logical || 276 rr_count = result[t ? 1 : 0]; 277 p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count; 278 d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data 279 th = result[2]; // headers 280 } 281 l = d.length; 282 if (d instanceof jQuery) { 283 // append jQuery object 284 c.$tbodies.eq(0).empty().append(d); 285 } else if (l) { 286 // build table from array 287 for ( i = 0; i < l; i++ ) { 288 tds += '<tr>'; 289 for ( j = 0; j < d[i].length; j++ ) { 290 // build tbody cells; watch for data containing HTML markup - see #434 291 tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>'; 292 } 293 tds += '</tr>'; 294 } 295 // add rows to first tbody 296 p.processAjaxOnInit ? c.$tbodies.eq(0).html( tds ) : p.processAjaxOnInit = true; 297 } 298 // only add new header text if the length matches 299 if ( th && th.length === hl ) { 300 hsh = $t.hasClass('hasStickyHeaders'); 301 $sh = hsh ? c.widgetOptions.$sticky.children('thead:first').children().children() : ''; 302 $f = $t.find('tfoot tr:first').children(); 303 // don't change td headers (may contain pager) 304 c.$headers.filter('th').each(function(j){ 305 var $t = $(this), icn; 306 // add new test within the first span it finds, or just in the header 307 if ( $t.find('.' + ts.css.icon).length ) { 308 icn = $t.find('.' + ts.css.icon).clone(true); 309 $t.find('.tablesorter-header-inner').html( th[j] ).append(icn); 310 if ( hsh && $sh.length ) { 311 icn = $sh.eq(j).find('.' + ts.css.icon).clone(true); 312 $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn); 313 } 314 } else { 315 $t.find('.tablesorter-header-inner').html( th[j] ); 316 if (hsh && $sh.length) { 317 $sh.eq(j).find('.tablesorter-header-inner').html( th[j] ); 318 } 319 } 320 $f.eq(j).html( th[j] ); 26 321 }); 27 322 } 28 c.pagerPositionSet = true; 29 } 30 } 31 32 function moveToFirstPage(table) { 33 var c = table.config; 34 c.page = 0; 35 moveToPage(table); 36 } 37 38 function moveToLastPage(table) { 39 var c = table.config; 40 c.page = (c.totalPages-1); 41 moveToPage(table); 42 } 43 44 function moveToNextPage(table) { 45 var c = table.config; 46 c.page++; 47 if(c.page >= (c.totalPages-1)) { 48 c.page = (c.totalPages-1); 49 } 50 moveToPage(table); 51 } 52 53 function moveToPrevPage(table) { 54 var c = table.config; 55 c.page--; 56 if(c.page <= 0) { 57 c.page = 0; 58 } 59 moveToPage(table); 60 } 61 62 63 function moveToPage(table) { 64 var c = table.config; 65 if(c.page < 0 || c.page > (c.totalPages-1)) { 66 c.page = 0; 67 } 68 69 renderTable(table,c.rowsCopy); 70 } 71 72 function renderTable(table,rows) { 73 74 var c = table.config; 75 var l = rows.length; 76 var s = (c.page * c.size); 77 var e = (s + c.size); 78 if(e > rows.length ) { 323 } 324 if (c.showProcessing) { 325 ts.isProcessing(table); // remove loading icon 326 } 327 // make sure last pager settings are saved, prevents multiple server side calls with 328 // the same parameters 329 p.last.totalPages = p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) ); 330 p.last.currentFilters = p.currentFilters; 331 p.last.sortList = (c.sortList || []).join(','); 332 updatePageDisplay(table, p); 333 fixHeight(table, p); 334 // apply widgets after table has rendered 335 $t.trigger('applyWidgets'); 336 $t.trigger('update', [false, function(){ 337 if (p.initialized) { 338 $t.trigger('updateComplete'); 339 $t.trigger('pagerChange', p); 340 } 341 }]); 342 } 343 if (!p.initialized) { 344 p.initialized = true; 345 $(table).trigger('pagerInitialized', p); 346 } 347 }, 348 349 getAjax = function(table, p){ 350 var url = getAjaxUrl(table, p), 351 $doc = $(document), 352 counter, 353 c = table.config; 354 if ( url !== '' ) { 355 if (c.showProcessing) { 356 ts.isProcessing(table, true); // show loading icon 357 } 358 $doc.bind('ajaxError.pager', function(e, xhr, settings, exception) { 359 renderAjax(null, table, p, xhr, exception); 360 $doc.unbind('ajaxError.pager'); 361 }); 362 363 counter = ++p.ajaxCounter; 364 365 p.ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl 366 p.ajaxObject.success = function(data) { 367 // Refuse to process old ajax commands that were overwritten by new ones - see #443 368 if (counter < p.ajaxCounter){ 369 return; 370 } 371 renderAjax(data, table, p); 372 $doc.unbind('ajaxError.pager'); 373 if (typeof p.oldAjaxSuccess === 'function') { 374 p.oldAjaxSuccess(data); 375 } 376 }; 377 if (c.debug) { 378 ts.log('ajax initialized', p.ajaxObject); 379 } 380 $.ajax(p.ajaxObject); 381 } 382 }, 383 384 getAjaxUrl = function(table, p) { 385 var c = table.config, 386 url = (p.ajaxUrl) ? p.ajaxUrl 387 // allow using "{page+1}" in the url string to switch to a non-zero based index 388 .replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); }) 389 .replace(/\{size\}/g, p.size) : '', 390 sl = c.sortList, 391 fl = p.currentFilters || $(table).data('lastSearch') || [], 392 sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/), 393 filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/), 394 arry = []; 395 if (sortCol) { 396 sortCol = sortCol[1]; 397 $.each(sl, function(i,v){ 398 arry.push(sortCol + '[' + v[0] + ']=' + v[1]); 399 }); 400 // if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col" 401 url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol ); 402 arry = []; 403 } 404 if (filterCol) { 405 filterCol = filterCol[1]; 406 $.each(fl, function(i,v){ 407 if (v) { 408 arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v)); 409 } 410 }); 411 // if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol" 412 url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol ); 413 p.currentFilters = fl; 414 } 415 if ( typeof(p.customAjaxUrl) === "function" ) { 416 url = p.customAjaxUrl(table, url); 417 } 418 if (c.debug) { 419 ts.log('Pager ajax url: ' + url); 420 } 421 return url; 422 }, 423 424 renderTable = function(table, rows, p) { 425 var i, $tb, 426 l = rows && rows.length || 0, // rows may be undefined 427 s = ( p.page * p.size ), 428 e = ( s + p.size ); 429 if ( l < 1 ) { return; } // empty table, abort! 430 if ( p.page >= p.totalPages ) { 431 // lets not render the table more than once 432 moveToLastPage(table, p); 433 } 434 p.isDisabled = false; // needed because sorting will change the page and re-enable the pager 435 if (p.initialized) { $(table).trigger('pagerChange', p); } 436 437 if ( !p.removeRows ) { 438 hideRows(table, p); 439 } else { 440 if ( e > rows.length ) { 79 441 e = rows.length; 80 442 } 81 82 83 var tableBody = $(table.tBodies[0]); 84 85 // clear the table body 86 87 $.tablesorter.clearTableBody(table); 88 89 for(var i = s; i < e; i++) { 90 91 //tableBody.append(rows[i]); 92 93 var o = rows[i]; 94 var l = o.length; 95 for(var j=0; j < l; j++) { 96 97 tableBody[0].appendChild(o[j]); 98 99 } 100 } 101 102 fixPosition(table,tableBody); 103 104 $(table).trigger("applyWidgets"); 105 106 if( c.page >= c.totalPages ) { 107 moveToLastPage(table); 108 } 109 110 updatePageDisplay(c); 111 } 112 113 this.appender = function(table,rows) { 114 115 var c = table.config; 116 443 ts.clearTableBody(table); 444 $tb = ts.processTbody(table, table.config.$tbodies.eq(0), true); 445 for ( i = s; i < e; i++ ) { 446 $tb.append(rows[i]); 447 } 448 ts.processTbody(table, $tb, false); 449 } 450 451 updatePageDisplay(table, p); 452 if ( !p.isDisabled ) { fixHeight(table, p); } 453 $(table).trigger('applyWidgets'); 454 }, 455 456 showAllRows = function(table, p){ 457 if ( p.ajax ) { 458 pagerArrows(p, true); 459 } else { 460 p.isDisabled = true; 461 $.data(table, 'pagerLastPage', p.page); 462 $.data(table, 'pagerLastSize', p.size); 463 p.page = 0; 464 p.size = p.totalRows; 465 p.totalPages = 1; 466 $(table).addClass('pagerDisabled').find('tr.pagerSavedHeightSpacer').remove(); 467 renderTable(table, table.config.rowsCopy, p); 468 if (table.config.debug) { 469 ts.log('pager disabled'); 470 } 471 } 472 // disable size selector 473 p.$size.add(p.$goto).each(function(){ 474 $(this).addClass(p.cssDisabled)[0].disabled = true; 475 }); 476 }, 477 478 moveToPage = function(table, p, flag) { 479 if ( p.isDisabled ) { return; } 480 var c = table.config, 481 l = p.last, 482 pg = Math.min( p.totalPages, p.filteredPages ); 483 if ( p.page < 0 ) { p.page = 0; } 484 if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; } 485 // don't allow rendering multiple times on the same page/size/totalpages/filters/sorts 486 if ( l.page === p.page && l.size === p.size && l.totalPages === p.totalPages && 487 (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') && 488 l.sortList === (c.sortList || []).join(',') ) { return; } 489 if (c.debug) { 490 ts.log('Pager changing to page ' + p.page); 491 } 492 p.last = { 493 page : p.page, 494 size : p.size, 495 // fixes #408; modify sortList otherwise it auto-updates 496 sortList : (c.sortList || []).join(','), 497 totalPages : p.totalPages, 498 currentFilters : p.currentFilters || [] 499 }; 500 if (p.ajax) { 501 getAjax(table, p); 502 } else if (!p.ajax) { 503 renderTable(table, table.config.rowsCopy, p); 504 } 505 $.data(table, 'pagerLastPage', p.page); 506 if (p.initialized && flag !== false) { 507 c.$table.trigger('pageMoved', p); 508 c.$table.trigger('applyWidgets'); 509 } 510 }, 511 512 setPageSize = function(table, size, p) { 513 p.size = size || p.size || 10; 514 p.$size.val(p.size); 515 $.data(table, 'pagerLastPage', p.page); 516 $.data(table, 'pagerLastSize', p.size); 517 p.totalPages = Math.ceil( p.totalRows / p.size ); 518 moveToPage(table, p); 519 }, 520 521 moveToFirstPage = function(table, p) { 522 p.page = 0; 523 moveToPage(table, p); 524 }, 525 526 moveToLastPage = function(table, p) { 527 p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 ); 528 moveToPage(table, p); 529 }, 530 531 moveToNextPage = function(table, p) { 532 p.page++; 533 if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) { 534 p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 ); 535 } 536 moveToPage(table, p); 537 }, 538 539 moveToPrevPage = function(table, p) { 540 p.page--; 541 if ( p.page <= 0 ) { 542 p.page = 0; 543 } 544 moveToPage(table, p); 545 }, 546 547 destroyPager = function(table, p){ 548 showAllRows(table, p); 549 p.$container.hide(); // hide pager 550 table.config.appender = null; // remove pager appender function 551 p.initialized = false; 552 $(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager'); 553 if (ts.storage) { 554 ts.storage(table, 'tablesorter-pager', ''); 555 } 556 }, 557 558 enablePager = function(table, p, triggered){ 559 var pg = p.$size.removeClass(p.cssDisabled).removeAttr('disabled'); 560 p.$goto.removeClass(p.cssDisabled).removeAttr('disabled'); 561 p.isDisabled = false; 562 p.page = $.data(table, 'pagerLastPage') || p.page || 0; 563 p.size = $.data(table, 'pagerLastSize') || parseInt(pg.find('option[selected]').val(), 10) || p.size || 10; 564 pg.val(p.size); // set page size 565 p.totalPages = Math.ceil( Math.min( p.totalPages, p.filteredPages ) / p.size ); 566 if ( triggered ) { 567 $(table).trigger('update'); 568 setPageSize(table, p.size, p); 569 hideRowsSetup(table, p); 570 fixHeight(table, p); 571 if (table.config.debug) { 572 ts.log('pager enabled'); 573 } 574 } 575 }; 576 577 $this.appender = function(table, rows) { 578 var c = table.config, 579 p = c.pager; 580 if ( !p.ajax ) { 117 581 c.rowsCopy = rows; 118 c.totalRows = rows.length; 119 c.totalPages = Math.ceil(c.totalRows / c.size); 120 121 renderTable(table,rows); 122 }; 123 124 this.defaults = { 125 size: 10, 126 offset: 0, 127 page: 0, 128 totalRows: 0, 129 totalPages: 0, 130 container: null, 131 cssNext: '.next', 132 cssPrev: '.prev', 133 cssFirst: '.first', 134 cssLast: '.last', 135 cssPageDisplay: '.pagedisplay', 136 cssPageSize: '.pagesize', 137 seperator: "/", 138 positionFixed: true, 139 appender: this.appender 140 }; 141 142 this.construct = function(settings) { 143 144 return this.each(function() { 145 146 config = $.extend(this.config, $.tablesorterPager.defaults, settings); 147 148 var table = this, pager = config.container; 149 150 $(this).trigger("appendCache"); 151 152 config.size = parseInt($(".pagesize",pager).val()); 153 154 $(config.cssFirst,pager).click(function() { 155 moveToFirstPage(table); 582 p.totalRows = p.countChildRows ? c.$tbodies.eq(0).children().length : rows.length; 583 p.size = $.data(table, 'pagerLastSize') || p.size || 10; 584 p.totalPages = Math.ceil( p.totalRows / p.size ); 585 renderTable(table, rows, p); 586 } 587 }; 588 589 $this.construct = function(settings) { 590 return this.each(function() { 591 // check if tablesorter has initialized 592 if (!(this.config && this.hasInitialized)) { return; } 593 var t, ctrls, fxn, 594 table = this, 595 c = table.config, 596 p = c.pager = $.extend( {}, $.tablesorterPager.defaults, settings ), 597 $t = c.$table, 598 // added in case the pager is reinitialized after being destroyed. 599 pager = p.$container = $(p.container).addClass('tablesorter-pager').show(); 600 if (c.debug) { 601 ts.log('Pager initializing'); 602 } 603 p.oldAjaxSuccess = p.oldAjaxSuccess || p.ajaxObject.success; 604 c.appender = $this.appender; 605 if (ts.filter && $.inArray('filter', c.widgets) >= 0) { 606 // get any default filter settings (data-value attribute) fixes #388 607 p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, c.widgetOptions) || []; 608 // set, but don't apply current filters 609 ts.setFilters(table, p.currentFilters, false); 610 } 611 if (p.savePages && ts.storage) { 612 t = ts.storage(table, 'tablesorter-pager') || {}; // fixes #387 613 p.page = isNaN(t.page) ? p.page : t.page; 614 p.size = ( isNaN(t.size) ? p.size : t.size ) || 10; 615 $.data(table, 'pagerLastSize', p.size); 616 } 617 618 $t 619 .unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager ')) 620 .bind('filterStart.pager', function(e, filters) { 621 p.currentFilters = filters; 622 p.page = 0; // fixes #456 623 }) 624 // update pager after filter widget completes 625 .bind('filterEnd.pager sortEnd.pager', function() { 626 if (p.initialized) { 627 moveToPage(table, p, false); 628 updatePageDisplay(table, p, false); 629 fixHeight(table, p); 630 } 631 }) 632 .bind('disable.pager', function(e){ 633 e.stopPropagation(); 634 showAllRows(table, p); 635 }) 636 .bind('enable.pager', function(e){ 637 e.stopPropagation(); 638 enablePager(table, p, true); 639 }) 640 .bind('destroy.pager', function(e){ 641 e.stopPropagation(); 642 destroyPager(table, p); 643 }) 644 .bind('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){ 645 e.stopPropagation(); 646 hideRows(table, p); 647 }) 648 .bind('pageSize.pager', function(e,v){ 649 e.stopPropagation(); 650 setPageSize(table, parseInt(v, 10) || 10, p); 651 hideRows(table, p); 652 updatePageDisplay(table, p, false); 653 if (p.$size.length) { p.$size.val(p.size); } // twice? 654 }) 655 .bind('pageSet.pager', function(e,v){ 656 e.stopPropagation(); 657 p.page = (parseInt(v, 10) || 1) - 1; 658 if (p.$goto.length) { p.$goto.val(p.size); } // twice? 659 moveToPage(table, p); 660 updatePageDisplay(table, p, false); 661 }); 662 663 // clicked controls 664 ctrls = [ p.cssFirst, p.cssPrev, p.cssNext, p.cssLast ]; 665 fxn = [ moveToFirstPage, moveToPrevPage, moveToNextPage, moveToLastPage ]; 666 pager.find(ctrls.join(',')) 667 .unbind('click.pager') 668 .bind('click.pager', function(e){ 669 e.stopPropagation(); 670 var i, $t = $(this), l = ctrls.length; 671 if ( !$t.hasClass(p.cssDisabled) ) { 672 for (i = 0; i < l; i++) { 673 if ($t.is(ctrls[i])) { 674 fxn[i](table, p); 675 break; 676 } 677 } 678 } 679 }); 680 681 // goto selector 682 p.$goto = pager.find(p.cssGoto); 683 if ( p.$goto.length ) { 684 p.$goto 685 .unbind('change') 686 .bind('change', function(){ 687 p.page = $(this).val() - 1; 688 moveToPage(table, p); 689 updatePageDisplay(table, p, false); 690 }); 691 } 692 693 // page size selector 694 p.$size = pager.find(p.cssPageSize); 695 if ( p.$size.length ) { 696 p.$size.unbind('change.pager').bind('change.pager', function() { 697 p.$size.val( $(this).val() ); // in case there are more than one pagers 698 if ( !$(this).hasClass(p.cssDisabled) ) { 699 setPageSize(table, parseInt( $(this).val(), 10 ), p); 700 changeHeight(table, p); 701 } 156 702 return false; 157 703 }); 158 $(config.cssNext,pager).click(function() { 159 moveToNextPage(table); 160 return false; 161 }); 162 $(config.cssPrev,pager).click(function() { 163 moveToPrevPage(table); 164 return false; 165 }); 166 $(config.cssLast,pager).click(function() { 167 moveToLastPage(table); 168 return false; 169 }); 170 $(config.cssPageSize,pager).change(function() { 171 setPageSize(table,parseInt($(this).val())); 172 return false; 173 }); 174 }); 175 }; 176 177 } 178 }); 179 // extend plugin scope 180 $.fn.extend({ 181 tablesorterPager: $.tablesorterPager.construct 182 }); 183 184 })(jQuery); 704 } 705 706 // clear initialized flag 707 p.initialized = false; 708 // before initialization event 709 $t.trigger('pagerBeforeInitialized', p); 710 711 enablePager(table, p, false); 712 713 if ( typeof(p.ajaxUrl) === 'string' ) { 714 // ajax pager; interact with database 715 p.ajax = true; 716 //When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side. 717 c.widgetOptions.filter_serversideFiltering = true; 718 c.serverSideSorting = true; 719 moveToPage(table, p); 720 } else { 721 p.ajax = false; 722 // Regular pager; all rows stored in memory 723 $(this).trigger("appendCache", true); 724 hideRowsSetup(table, p); 725 } 726 727 changeHeight(table, p); 728 729 // pager initialized 730 if (!p.ajax) { 731 p.initialized = true; 732 $(table).trigger('pagerInitialized', p); 733 } 734 }); 735 }; 736 737 }() 738 }); 739 // extend plugin scope 740 $.fn.extend({ 741 tablesorterPager: $.tablesorterPager.construct 742 }); 743 744 })(jQuery);
Note: See TracChangeset
for help on using the changeset viewer.