jquery-tablesorter 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/README.markdown +3 -1
  2. data/lib/jquery-tablesorter/version.rb +1 -1
  3. data/vendor/assets/images/jquery-tablesorter/black-asc.gif +0 -0
  4. data/vendor/assets/images/jquery-tablesorter/black-desc.gif +0 -0
  5. data/vendor/assets/images/jquery-tablesorter/dropbox-asc-hovered.png +0 -0
  6. data/vendor/assets/images/jquery-tablesorter/dropbox-asc.png +0 -0
  7. data/vendor/assets/images/jquery-tablesorter/dropbox-desc-hovered.png +0 -0
  8. data/vendor/assets/images/jquery-tablesorter/dropbox-desc.png +0 -0
  9. data/vendor/assets/images/jquery-tablesorter/green-asc.gif +0 -0
  10. data/vendor/assets/images/jquery-tablesorter/green-desc.gif +0 -0
  11. data/vendor/assets/images/jquery-tablesorter/green-header.gif +0 -0
  12. data/vendor/assets/images/jquery-tablesorter/green-unsorted.gif +0 -0
  13. data/vendor/assets/images/jquery-tablesorter/ice-asc.gif +0 -0
  14. data/vendor/assets/images/jquery-tablesorter/ice-desc.gif +0 -0
  15. data/vendor/assets/images/jquery-tablesorter/ice-unsorted.gif +0 -0
  16. data/vendor/assets/images/jquery-tablesorter/white-asc.gif +0 -0
  17. data/vendor/assets/images/jquery-tablesorter/white-desc.gif +0 -0
  18. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +507 -507
  19. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +72 -63
  20. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.min.js +2 -3
  21. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +17 -12
  22. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.min.js +8 -8
  23. data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +12 -8
  24. data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +14 -10
  25. data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +10 -4
  26. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +12 -8
  27. data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +9 -6
  28. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +29 -18
  29. data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +15 -6
  30. data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +12 -10
  31. data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +20 -10
  32. data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +7 -1
  33. metadata +17 -15
@@ -1,8 +1,10 @@
1
1
  # jQuery Table Sorter plugin for Rails
2
2
 
3
+ [![Still Maintained](http://stillmaintained.com/linjunpop/jquery-tablesorter-rails.png)](http://stillmaintained.com/linjunpop/jquery-tablesorter-rails)
4
+
3
5
  Simple integration of jquery-tablesorter into the asset pipeline.
4
6
 
5
- Current tablesorter version: 2.4.6 (10/25/2012), [documentation]
7
+ Current tablesorter version: 2.5.2 (11/27/2012), [documentation]
6
8
 
7
9
  Any issue associate with the js/css files, please report to [Mottie's fork].
8
10
 
@@ -1,3 +1,3 @@
1
1
  module JqueryTablesorter
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,508 +1,508 @@
1
- /*!
2
- * tablesorter pager plugin
3
- * updated 10/25/2012
4
- */
5
- /*jshint browser:true, jquery:true */
6
- ;(function($) {
7
- "use strict";
8
- $.extend({tablesorterPager: new function() {
9
-
10
- this.defaults = {
11
- // target the pager markup
12
- container: null,
13
-
14
- // use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}"
15
- // where {page} is replaced by the page number and {size} is replaced by the number of records to show
16
- // {sortList:col} adds the sortList to the url into a "col" array.
17
- // So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
18
- ajaxUrl: null,
19
-
20
- // process ajax so that the following information is returned:
21
- // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
22
- // example:
23
- // [
24
- // 100, // total rows
25
- // [
26
- // [ "row1cell1", "row1cell2", ... "row1cellN" ],
27
- // [ "row2cell1", "row2cell2", ... "row2cellN" ],
28
- // ...
29
- // [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
30
- // ],
31
- // [ "header1", "header2", ... "headerN" ] // optional
32
- // ]
33
- ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
34
-
35
- // output default: '{page}/{totalPages}'
36
- // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
37
- output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
38
-
39
- // apply disabled classname to the pager arrows when the rows at either extreme is visible
40
- updateArrows: true,
41
-
42
- // starting page of the pager (zero based index)
43
- page: 0,
44
-
45
- // Number of visible rows
46
- size: 10,
47
-
48
- // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
49
- // table row set to a height to compensate; default is false
50
- fixedHeight: false,
51
-
52
- // remove rows from the table to speed up the sort of large tables.
53
- // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
54
- removeRows: false, // removing rows in larger tables speeds up the sort
55
-
56
- // css class names of pager arrows
57
- cssFirst: '.first', // go to first page arrow
58
- cssPrev: '.prev', // previous page arrow
59
- cssNext: '.next', // next page arrow
60
- cssLast: '.last', // go to last page arrow
61
- cssGoto: '.gotoPage', // go to page selector - select dropdown that sets the current page
62
- cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed
63
- cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option
64
-
65
- // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
66
- cssDisabled: 'disabled', // Note there is no period "." in front of this class name
67
-
68
- // stuff not set by the user
69
- totalRows: 0,
70
- totalPages: 0,
71
- filteredRows: 0,
72
- filteredPages: 0
73
-
74
- };
75
-
76
- var $this = this,
77
-
78
- // hide arrows at extremes
79
- pagerArrows = function(c, disable) {
80
- var a = 'addClass',
81
- r = 'removeClass',
82
- d = c.cssDisabled,
83
- dis = !!disable,
84
- // tr = Math.min( c.totalRows, c.filteredRows ),
85
- tp = Math.min( c.totalPages, c.filteredPages );
86
- if ( c.updateArrows ) {
87
- $(c.cssFirst + ',' + c.cssPrev, c.container)[ ( dis || c.page === 0 ) ? a : r ](d);
88
- $(c.cssNext + ',' + c.cssLast, c.container)[ ( dis || c.page === tp - 1 ) ? a : r ](d);
89
- }
90
- },
91
-
92
- updatePageDisplay = function(table, c) {
93
- var i, p, s, t, out, f = $(table).hasClass('hasFilters');
94
- c.filteredRows = (f) ? $(table).find('tbody tr:not(.filtered)').length : c.totalRows;
95
- c.filteredPages = (f) ? Math.ceil( c.filteredRows / c.size ) : c.totalPages;
96
- if ( Math.min( c.totalPages, c.filteredPages ) > 0 ) {
97
- t = (c.size * c.page > c.filteredRows);
98
- c.startRow = (t) ? 1 : ( c.size * c.page ) + 1;
99
- c.page = (t) ? 0 : c.page;
100
- c.endRow = Math.min( c.filteredRows, c.totalRows, c.size * ( c.page + 1 ) );
101
- out = $(c.cssPageDisplay, c.container);
102
- // form the output string
103
- s = c.output.replace(/\{(page|filteredRows|filteredPages|totalPages|startRow|endRow|totalRows)\}/gi, function(m){
104
- return {
105
- '{page}' : c.page + 1,
106
- '{filteredRows}' : c.filteredRows,
107
- '{filteredPages}' : c.filteredPages,
108
- '{totalPages}' : c.totalPages,
109
- '{startRow}' : c.startRow,
110
- '{endRow}' : c.endRow,
111
- '{totalRows}' : c.totalRows
112
- }[m];
113
- });
114
- if (out[0]) {
115
- out[ (out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
116
- if ( $(c.cssGoto, c.container).length ) {
117
- t = '';
118
- p = Math.min( c.totalPages, c.filteredPages );
119
- for ( i = 1; i <= p; i++ ) {
120
- t += '<option>' + i + '</option>';
121
- }
122
- $(c.cssGoto, c.container).html(t).val(c.page + 1);
123
- }
124
- }
125
- }
126
- pagerArrows(c);
127
- if (c.initialized) { $(table).trigger('pagerComplete', c); }
128
- },
129
-
130
- fixHeight = function(table, c) {
131
- var d, h, $b = $(table.tBodies[0]);
132
- if (c.fixedHeight) {
133
- $b.find('tr.pagerSavedHeightSpacer').remove();
134
- h = $.data(table, 'pagerSavedHeight');
135
- if (h) {
136
- d = h - $b.height();
137
- if ( d > 5 && $.data(table, 'pagerLastSize') === c.size && $b.find('tr:visible').length < c.size ) {
138
- $b.append('<tr class="pagerSavedHeightSpacer remove-me" style="height:' + d + 'px;"></tr>');
139
- }
140
- }
141
- }
142
- },
143
-
144
- changeHeight = function(table, c) {
145
- var $b = $(table.tBodies[0]);
146
- $b.find('tr.pagerSavedHeightSpacer').remove();
147
- $.data(table, 'pagerSavedHeight', $b.height());
148
- fixHeight(table, c);
149
- $.data(table, 'pagerLastSize', c.size);
150
- },
151
-
152
- hideRows = function(table, c){
153
- if (!c.ajaxUrl) {
154
- var i,
155
- rows = $('tr:not(.' + table.config.cssChildRow + ')', table.tBodies),
156
- l = rows.length,
157
- s = ( c.page * c.size ),
158
- e = s + c.size,
159
- j = 0; // size counter
160
- for ( i = 0; i < l; i++ ){
161
- if (!/filtered/.test(rows[i].className)) {
162
- rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
163
- j++;
164
- }
165
- }
166
- }
167
- },
168
-
169
- hideRowsSetup = function(table, c){
170
- c.size = parseInt( $(c.cssPageSize, c.container).find('option[selected]').val(), 10 ) || c.size;
171
- $.data(table, 'pagerLastSize', c.size);
172
- pagerArrows(c);
173
- if ( !c.removeRows ) {
174
- hideRows(table, c);
175
- $(table).bind('sortEnd.pager filterEnd.pager', function(){
176
- hideRows(table, c);
177
- });
178
- }
179
- },
180
-
181
- renderAjax = function(data, table, c, exception){
182
- // process data
183
- if ( typeof(c.ajaxProcessing) === "function" ) {
184
- // ajaxProcessing result: [ total, rows, headers ]
185
- var i, j, hsh, $f, $sh,
186
- $t = $(table),
187
- tc = table.config,
188
- $b = $(table.tBodies).filter(':not(.' + tc.cssInfoBlock + ')'),
189
- hl = $t.find('thead th').length, tds = '',
190
- err = '<tr class="' + tc.selectorRemove + '"><td style="text-align: center;" colspan="' + hl + '">' +
191
- (exception ? exception.message + ' (' + exception.name + ')' : 'No rows found') + '</td></tr>',
192
- result = c.ajaxProcessing(data) || [ 0, [] ],
193
- d = result[1] || [],
194
- l = d.length,
195
- th = result[2];
196
- if ( l > 0 ) {
197
- for ( i = 0; i < l; i++ ) {
198
- tds += '<tr>';
199
- for ( j = 0; j < d[i].length; j++ ) {
200
- // build tbody cells
201
- tds += '<td>' + d[i][j] + '</td>';
202
- }
203
- tds += '</tr>';
204
- }
205
- }
206
- // only add new header text if the length matches
207
- if ( th && th.length === hl ) {
208
- hsh = $t.hasClass('hasStickyHeaders');
209
- $sh = $t.find('.' + ((tc.widgetOptions && tc.widgetOptions.stickyHeaders) || 'tablesorter-stickyheader'));
210
- $f = $t.find('tfoot tr:first').children();
211
- $t.find('th.' + tc.cssHeader).each(function(j){
212
- var $t = $(this), icn;
213
- // add new test within the first span it finds, or just in the header
214
- if ( $t.find('.' + tc.cssIcon).length ) {
215
- icn = $t.find('.' + tc.cssIcon).clone(true);
216
- $t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
217
- if ( hsh && $sh.length ) {
218
- icn = $sh.find('th').eq(j).find('.' + tc.cssIcon).clone(true);
219
- $sh.find('th').eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
220
- }
221
- } else {
222
- $t.find('.tablesorter-header-inner').html( th[j] );
223
- $sh.find('th').eq(j).find('.tablesorter-header-inner').html( th[j] );
224
- }
225
- $f.eq(j).html( th[j] );
226
- });
227
- }
228
- if ( exception ) {
229
- // add error row to thead instead of tbody, or clicking on the header will result in a parser error
230
- $t.find('thead').append(err);
231
- } else {
232
- $b.html( tds ); // add tbody
233
- }
234
- c.temp.remove(); // remove loading icon
235
- $t.trigger('update');
236
- c.totalRows = result[0] || 0;
237
- c.totalPages = Math.ceil( c.totalRows / c.size );
238
- updatePageDisplay(table, c);
239
- fixHeight(table, c);
240
- if (c.initialized) { $t.trigger('pagerChange', c); }
241
- }
242
- if (!c.initialized) {
243
- c.initialized = true;
244
- $(table).trigger('pagerInitialized', c);
245
- }
246
- },
247
-
248
- getAjax = function(table, c){
249
- var $t = $(table),
250
- url = (c.ajaxUrl) ? c.ajaxUrl.replace(/\{page\}/g, c.page).replace(/\{size\}/g, c.size) : '',
251
- arry = [],
252
- sl = table.config.sortList,
253
- col = url.match(/\{sortList[\s+]?:[\s+]?(.*)\}/);
254
- if (col) {
255
- col = col[1];
256
- $.each(sl, function(i,v){
257
- arry.push(col + '[' + v[0] + ']=' + v[1]);
258
- });
259
- // if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
260
- url = url.replace(/\{sortList[\s+]?:[\s+]?(.*)\}/g, arry.length ? arry.join('&') : col );
261
- }
262
- if ( url !== '' ) {
263
- // loading icon
264
- c.temp = $('<div/>', {
265
- 'class' : 'tablesorter-processing',
266
- width : $t.outerWidth(true),
267
- height: $t.outerHeight(true)
268
- });
269
- $t.before( c.temp );
270
- $(document).ajaxError(function(e, xhr, settings, exception) {
271
- renderAjax(null, table, c, exception);
272
- });
273
- $.getJSON(url, function(data) {
274
- renderAjax(data, table, c);
275
- });
276
- }
277
- },
278
-
279
- renderTable = function(table, rows, c) {
280
- var i, j, o,
281
- f = document.createDocumentFragment(),
282
- l = rows.length,
283
- s = ( c.page * c.size ),
284
- e = ( s + c.size );
285
- if ( l < 1 ) { return; } // empty table, abort!
286
- if (c.initialized) { $(table).trigger('pagerChange', c); }
287
- if ( !c.removeRows ) {
288
- hideRows(table, c);
289
- } else {
290
- if ( e > rows.length ) {
291
- e = rows.length;
292
- }
293
- $(table.tBodies[0]).addClass('tablesorter-hidden');
294
- $.tablesorter.clearTableBody(table);
295
- for ( i = s; i < e; i++ ) {
296
- o = rows[i];
297
- l = o.length;
298
- for ( j = 0; j < l; j++ ) {
299
- f.appendChild(o[j]);
300
- }
301
- }
302
- table.tBodies[0].appendChild(f);
303
- $(table.tBodies[0]).removeClass('tablesorter-hidden');
304
- }
305
- if ( c.page >= c.totalPages ) {
306
- moveToLastPage(table, c);
307
- }
308
- updatePageDisplay(table, c);
309
- if ( !c.isDisabled ) { fixHeight(table, c); }
310
- $(table).trigger('applyWidgets');
311
- },
312
-
313
- showAllRows = function(table, c){
314
- if ( c.ajax ) {
315
- pagerArrows(c, true);
316
- } else {
317
- c.isDisabled = true;
318
- $.data(table, 'pagerLastPage', c.page);
319
- $.data(table, 'pagerLastSize', c.size);
320
- c.page = 0;
321
- c.size = c.totalRows;
322
- c.totalPages = 1;
323
- $('tr.pagerSavedHeightSpacer', table.tBodies[0]).remove();
324
- renderTable(table, table.config.rowsCopy, c);
325
- }
326
- // disable size selector
327
- $(c.container).find(c.cssPageSize + ',' + c.cssGoto).each(function(){
328
- $(this).addClass(c.cssDisabled)[0].disabled = true;
329
- });
330
- },
331
-
332
- moveToPage = function(table, c) {
333
- if ( c.isDisabled ) { return; }
334
- var p = Math.min( c.totalPages, c.filteredPages );
335
- if ( c.page < 0 || c.page > ( p - 1 ) ) {
336
- c.page = 0;
337
- }
338
- $.data(table, 'pagerLastPage', c.page);
339
- if ( c.ajax ) {
340
- getAjax(table, c);
341
- } else {
342
- renderTable(table, table.config.rowsCopy, c);
343
- }
344
- if (c.initialized) { $(table).trigger('pageMoved', c); }
345
- },
346
-
347
- setPageSize = function(table, size, c) {
348
- c.size = size;
349
- $.data(table, 'pagerLastPage', c.page);
350
- $.data(table, 'pagerLastSize', c.size);
351
- c.totalPages = Math.ceil( c.totalRows / c.size );
352
- moveToPage(table, c);
353
- },
354
-
355
- moveToFirstPage = function(table, c) {
356
- c.page = 0;
357
- moveToPage(table, c);
358
- },
359
-
360
- moveToLastPage = function(table, c) {
361
- c.page = ( Math.min( c.totalPages, c.filteredPages ) - 1 );
362
- moveToPage(table, c);
363
- },
364
-
365
- moveToNextPage = function(table, c) {
366
- c.page++;
367
- if ( c.page >= ( Math.min( c.totalPages, c.filteredPages ) - 1 ) ) {
368
- c.page = ( Math.min( c.totalPages, c.filteredPages ) - 1 );
369
- }
370
- moveToPage(table, c);
371
- },
372
-
373
- moveToPrevPage = function(table, c) {
374
- c.page--;
375
- if ( c.page <= 0 ) {
376
- c.page = 0;
377
- }
378
- moveToPage(table, c);
379
- },
380
-
381
- destroyPager = function(table, c){
382
- showAllRows(table, c);
383
- $(c.container).hide(); // hide pager
384
- table.config.appender = null; // remove pager appender function
385
- $(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
386
- },
387
-
388
- enablePager = function(table, c, triggered){
389
- var p = $(c.cssPageSize, c.container).removeClass(c.cssDisabled).removeAttr('disabled');
390
- c.isDisabled = false;
391
- c.page = $.data(table, 'pagerLastPage') || c.page || 0;
392
- c.size = $.data(table, 'pagerLastSize') || parseInt(p.find('option[selected]').val(), 10) || c.size;
393
- p.val(c.size); // set page size
394
- c.totalPages = Math.ceil( Math.min( c.totalPages, c.filteredPages ) / c.size);
395
- if ( triggered ) {
396
- $(table).trigger('update');
397
- setPageSize(table, c.size, c);
398
- hideRowsSetup(table, c);
399
- fixHeight(table, c);
400
- }
401
- };
402
-
403
- $this.appender = function(table, rows) {
404
- var c = table.config.pager;
405
- if ( !c.ajax ) {
406
- table.config.rowsCopy = rows;
407
- c.totalRows = rows.length;
408
- c.size = $.data(table, 'pagerLastSize') || c.size;
409
- c.totalPages = Math.ceil(c.totalRows / c.size);
410
- renderTable(table, rows, c);
411
- }
412
- };
413
-
414
- $this.construct = function(settings) {
415
- return this.each(function() {
416
- var config = this.config,
417
- c = config.pager = $.extend( {}, $.tablesorterPager.defaults, settings ),
418
- table = this,
419
- $t = $(table),
420
- pager = $(c.container).addClass('tablesorter-pager').show(); // added in case the pager is reinitialized after being destroyed.
421
- config.appender = $this.appender;
422
- // clear initialized flag
423
- c.initialized = false;
424
- enablePager(table, c, false);
425
- if ( typeof(c.ajaxUrl) === 'string' ) {
426
- // ajax pager; interact with database
427
- c.ajax = true;
428
- getAjax(table, c);
429
- } else {
430
- c.ajax = false;
431
- // Regular pager; all rows stored in memory
432
- $(this).trigger("appendCache", true);
433
- hideRowsSetup(table, c);
434
- }
435
-
436
- // update pager after filter widget completes
437
- $(table)
438
- .unbind('filterEnd.pager updateComplete.pager ')
439
- .bind('filterEnd.pager updateComplete.pager', function() {
440
- c.page = 0;
441
- updatePageDisplay(table, c);
442
- moveToPage(table, c);
443
- changeHeight(table, c);
444
- });
445
-
446
- if ( $(c.cssGoto, pager).length ) {
447
- $(c.cssGoto, pager).bind('change', function(){
448
- c.page = $(this).val() - 1;
449
- moveToPage(table, c);
450
- });
451
- updatePageDisplay(table, c);
452
- }
453
- $(c.cssFirst,pager).unbind('click.pager').bind('click.pager', function() {
454
- if ( !$(this).hasClass(c.cssDisabled) ) { moveToFirstPage(table, c); }
455
- return false;
456
- });
457
- $(c.cssNext,pager).unbind('click.pager').bind('click.pager', function() {
458
- if ( !$(this).hasClass(c.cssDisabled) ) { moveToNextPage(table, c); }
459
- return false;
460
- });
461
- $(c.cssPrev,pager).unbind('click.pager').bind('click.pager', function() {
462
- if ( !$(this).hasClass(c.cssDisabled) ) { moveToPrevPage(table, c); }
463
- return false;
464
- });
465
- $(c.cssLast,pager).unbind('click.pager').bind('click.pager', function() {
466
- if ( !$(this).hasClass(c.cssDisabled) ) { moveToLastPage(table, c); }
467
- return false;
468
- });
469
- $(c.cssPageSize,pager).unbind('change.pager').bind('change.pager', function() {
470
- $(c.cssPageSize,pager).val( $(this).val() ); // in case there are more than one pagers
471
- if ( !$(this).hasClass(c.cssDisabled) ) {
472
- setPageSize(table, parseInt( $(this).val(), 10 ), c);
473
- changeHeight(table, c);
474
- }
475
- return false;
476
- });
477
-
478
- $t
479
- .unbind('disable.pager enable.pager destroy.pager update.pager')
480
- .bind('disable.pager', function(){
481
- showAllRows(table, c);
482
- })
483
- .bind('enable.pager', function(){
484
- enablePager(table, c, true);
485
- })
486
- .bind('destroy.pager', function(){
487
- destroyPager(table, c);
488
- })
489
- .bind('update.pager', function(){
490
- hideRows(table, c);
491
- });
492
-
493
- // pager initialized
494
- if (!c.ajax) {
495
- c.initialized = true;
496
- $(table).trigger('pagerInitialized', c);
497
- }
498
- });
499
- };
500
-
501
- }()
502
- });
503
- // extend plugin scope
504
- $.fn.extend({
505
- tablesorterPager: $.tablesorterPager.construct
506
- });
507
-
1
+ /*!
2
+ * tablesorter pager plugin
3
+ * updated 11/27/2012
4
+ */
5
+ /*jshint browser:true, jquery:true, unused:false */
6
+ ;(function($) {
7
+ "use strict";
8
+ $.extend({tablesorterPager: new function() {
9
+
10
+ this.defaults = {
11
+ // target the pager markup
12
+ container: null,
13
+
14
+ // use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}"
15
+ // where {page} is replaced by the page number and {size} is replaced by the number of records to show
16
+ // {sortList:col} adds the sortList to the url into a "col" array.
17
+ // So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
18
+ ajaxUrl: null,
19
+
20
+ // process ajax so that the following information is returned:
21
+ // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
22
+ // example:
23
+ // [
24
+ // 100, // total rows
25
+ // [
26
+ // [ "row1cell1", "row1cell2", ... "row1cellN" ],
27
+ // [ "row2cell1", "row2cell2", ... "row2cellN" ],
28
+ // ...
29
+ // [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
30
+ // ],
31
+ // [ "header1", "header2", ... "headerN" ] // optional
32
+ // ]
33
+ ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
34
+
35
+ // output default: '{page}/{totalPages}'
36
+ // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
37
+ output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
38
+
39
+ // apply disabled classname to the pager arrows when the rows at either extreme is visible
40
+ updateArrows: true,
41
+
42
+ // starting page of the pager (zero based index)
43
+ page: 0,
44
+
45
+ // Number of visible rows
46
+ size: 10,
47
+
48
+ // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
49
+ // table row set to a height to compensate; default is false
50
+ fixedHeight: false,
51
+
52
+ // remove rows from the table to speed up the sort of large tables.
53
+ // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
54
+ removeRows: false, // removing rows in larger tables speeds up the sort
55
+
56
+ // css class names of pager arrows
57
+ cssFirst: '.first', // go to first page arrow
58
+ cssPrev: '.prev', // previous page arrow
59
+ cssNext: '.next', // next page arrow
60
+ cssLast: '.last', // go to last page arrow
61
+ cssGoto: '.gotoPage', // go to page selector - select dropdown that sets the current page
62
+ cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed
63
+ cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option
64
+
65
+ // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
66
+ cssDisabled: 'disabled', // Note there is no period "." in front of this class name
67
+
68
+ // stuff not set by the user
69
+ totalRows: 0,
70
+ totalPages: 0,
71
+ filteredRows: 0,
72
+ filteredPages: 0
73
+
74
+ };
75
+
76
+ var $this = this,
77
+
78
+ // hide arrows at extremes
79
+ pagerArrows = function(c, disable) {
80
+ var a = 'addClass',
81
+ r = 'removeClass',
82
+ d = c.cssDisabled,
83
+ dis = !!disable,
84
+ // tr = Math.min( c.totalRows, c.filteredRows ),
85
+ tp = Math.min( c.totalPages, c.filteredPages );
86
+ if ( c.updateArrows ) {
87
+ $(c.cssFirst + ',' + c.cssPrev, c.container)[ ( dis || c.page === 0 ) ? a : r ](d);
88
+ $(c.cssNext + ',' + c.cssLast, c.container)[ ( dis || c.page === tp - 1 ) ? a : r ](d);
89
+ }
90
+ },
91
+
92
+ updatePageDisplay = function(table, c) {
93
+ var i, p, s, t, out, f = $(table).hasClass('hasFilters');
94
+ c.filteredRows = (f) ? $(table).find('tbody tr:not(.filtered)').length : c.totalRows;
95
+ c.filteredPages = (f) ? Math.ceil( c.filteredRows / c.size ) : c.totalPages;
96
+ if ( Math.min( c.totalPages, c.filteredPages ) > 0 ) {
97
+ t = (c.size * c.page > c.filteredRows);
98
+ c.startRow = (t) ? 1 : ( c.size * c.page ) + 1;
99
+ c.page = (t) ? 0 : c.page;
100
+ c.endRow = Math.min( c.filteredRows, c.totalRows, c.size * ( c.page + 1 ) );
101
+ out = $(c.cssPageDisplay, c.container);
102
+ // form the output string
103
+ s = c.output.replace(/\{(page|filteredRows|filteredPages|totalPages|startRow|endRow|totalRows)\}/gi, function(m){
104
+ return {
105
+ '{page}' : c.page + 1,
106
+ '{filteredRows}' : c.filteredRows,
107
+ '{filteredPages}' : c.filteredPages,
108
+ '{totalPages}' : c.totalPages,
109
+ '{startRow}' : c.startRow,
110
+ '{endRow}' : c.endRow,
111
+ '{totalRows}' : c.totalRows
112
+ }[m];
113
+ });
114
+ if (out[0]) {
115
+ out[ (out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
116
+ if ( $(c.cssGoto, c.container).length ) {
117
+ t = '';
118
+ p = Math.min( c.totalPages, c.filteredPages );
119
+ for ( i = 1; i <= p; i++ ) {
120
+ t += '<option>' + i + '</option>';
121
+ }
122
+ $(c.cssGoto, c.container).html(t).val(c.page + 1);
123
+ }
124
+ }
125
+ }
126
+ pagerArrows(c);
127
+ if (c.initialized) { $(table).trigger('pagerComplete', c); }
128
+ },
129
+
130
+ fixHeight = function(table, c) {
131
+ var d, h, $b = $(table.tBodies[0]);
132
+ if (c.fixedHeight) {
133
+ $b.find('tr.pagerSavedHeightSpacer').remove();
134
+ h = $.data(table, 'pagerSavedHeight');
135
+ if (h) {
136
+ d = h - $b.height();
137
+ if ( d > 5 && $.data(table, 'pagerLastSize') === c.size && $b.find('tr:visible').length < c.size ) {
138
+ $b.append('<tr class="pagerSavedHeightSpacer remove-me" style="height:' + d + 'px;"></tr>');
139
+ }
140
+ }
141
+ }
142
+ },
143
+
144
+ changeHeight = function(table, c) {
145
+ var $b = $(table.tBodies[0]);
146
+ $b.find('tr.pagerSavedHeightSpacer').remove();
147
+ $.data(table, 'pagerSavedHeight', $b.height());
148
+ fixHeight(table, c);
149
+ $.data(table, 'pagerLastSize', c.size);
150
+ },
151
+
152
+ hideRows = function(table, c){
153
+ if (!c.ajaxUrl) {
154
+ var i,
155
+ rows = $('tr:not(.' + table.config.cssChildRow + ')', table.tBodies),
156
+ l = rows.length,
157
+ s = ( c.page * c.size ),
158
+ e = s + c.size,
159
+ j = 0; // size counter
160
+ for ( i = 0; i < l; i++ ){
161
+ if (!/filtered/.test(rows[i].className)) {
162
+ rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
163
+ j++;
164
+ }
165
+ }
166
+ }
167
+ },
168
+
169
+ hideRowsSetup = function(table, c){
170
+ c.size = parseInt( $(c.cssPageSize, c.container).find('option[selected]').val(), 10 ) || c.size;
171
+ $.data(table, 'pagerLastSize', c.size);
172
+ pagerArrows(c);
173
+ if ( !c.removeRows ) {
174
+ hideRows(table, c);
175
+ $(table).bind('sortEnd.pager filterEnd.pager', function(){
176
+ hideRows(table, c);
177
+ });
178
+ }
179
+ },
180
+
181
+ renderAjax = function(data, table, c, exception){
182
+ // process data
183
+ if ( typeof(c.ajaxProcessing) === "function" ) {
184
+ // ajaxProcessing result: [ total, rows, headers ]
185
+ var i, j, hsh, $f, $sh,
186
+ $t = $(table),
187
+ tc = table.config,
188
+ $b = $(table.tBodies).filter(':not(.' + tc.cssInfoBlock + ')'),
189
+ hl = $t.find('thead th').length, tds = '',
190
+ err = '<tr class="' + tc.selectorRemove + '"><td style="text-align: center;" colspan="' + hl + '">' +
191
+ (exception ? exception.message + ' (' + exception.name + ')' : 'No rows found') + '</td></tr>',
192
+ result = c.ajaxProcessing(data) || [ 0, [] ],
193
+ d = result[1] || [],
194
+ l = d.length,
195
+ th = result[2];
196
+ if ( l > 0 ) {
197
+ for ( i = 0; i < l; i++ ) {
198
+ tds += '<tr>';
199
+ for ( j = 0; j < d[i].length; j++ ) {
200
+ // build tbody cells
201
+ tds += '<td>' + d[i][j] + '</td>';
202
+ }
203
+ tds += '</tr>';
204
+ }
205
+ }
206
+ // only add new header text if the length matches
207
+ if ( th && th.length === hl ) {
208
+ hsh = $t.hasClass('hasStickyHeaders');
209
+ $sh = $t.find('.' + ((tc.widgetOptions && tc.widgetOptions.stickyHeaders) || 'tablesorter-stickyheader'));
210
+ $f = $t.find('tfoot tr:first').children();
211
+ $t.find('th.' + tc.cssHeader).each(function(j){
212
+ var $t = $(this), icn;
213
+ // add new test within the first span it finds, or just in the header
214
+ if ( $t.find('.' + tc.cssIcon).length ) {
215
+ icn = $t.find('.' + tc.cssIcon).clone(true);
216
+ $t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
217
+ if ( hsh && $sh.length ) {
218
+ icn = $sh.find('th').eq(j).find('.' + tc.cssIcon).clone(true);
219
+ $sh.find('th').eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
220
+ }
221
+ } else {
222
+ $t.find('.tablesorter-header-inner').html( th[j] );
223
+ $sh.find('th').eq(j).find('.tablesorter-header-inner').html( th[j] );
224
+ }
225
+ $f.eq(j).html( th[j] );
226
+ });
227
+ }
228
+ if ( exception ) {
229
+ // add error row to thead instead of tbody, or clicking on the header will result in a parser error
230
+ $t.find('thead').append(err);
231
+ } else {
232
+ $b.html( tds ); // add tbody
233
+ }
234
+ $.tablesorter.isProcessing(table); // remove loading icon
235
+ $t.trigger('update');
236
+ c.totalRows = result[0] || 0;
237
+ c.totalPages = Math.ceil( c.totalRows / c.size );
238
+ updatePageDisplay(table, c);
239
+ fixHeight(table, c);
240
+ if (c.initialized) { $t.trigger('pagerChange', c); }
241
+ }
242
+ if (!c.initialized) {
243
+ c.initialized = true;
244
+ $(table).trigger('pagerInitialized', c);
245
+ }
246
+ },
247
+
248
+ getAjax = function(table, c){
249
+ var url = (c.ajaxUrl) ? c.ajaxUrl.replace(/\{page\}/g, c.page).replace(/\{size\}/g, c.size) : '',
250
+ arry = [],
251
+ sl = table.config.sortList,
252
+ col = url.match(/\{sortList[\s+]?:[\s+]?(.*)\}/);
253
+ if (col) {
254
+ col = col[1];
255
+ $.each(sl, function(i,v){
256
+ arry.push(col + '[' + v[0] + ']=' + v[1]);
257
+ });
258
+ // if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
259
+ url = url.replace(/\{sortList[\s+]?:[\s+]?(.*)\}/g, arry.length ? arry.join('&') : col );
260
+ }
261
+ if ( url !== '' ) {
262
+ // loading icon
263
+ $.tablesorter.isProcessing(table, true);
264
+ $(document).ajaxError(function(e, xhr, settings, exception) {
265
+ renderAjax(null, table, c, exception);
266
+ });
267
+ $.getJSON(url, function(data) {
268
+ renderAjax(data, table, c);
269
+ });
270
+ }
271
+ },
272
+
273
+ renderTable = function(table, rows, c) {
274
+ var i, j, o,
275
+ f = document.createDocumentFragment(),
276
+ l = rows.length,
277
+ s = ( c.page * c.size ),
278
+ e = ( s + c.size );
279
+ if ( l < 1 ) { return; } // empty table, abort!
280
+ if (c.initialized) { $(table).trigger('pagerChange', c); }
281
+ if ( !c.removeRows ) {
282
+ hideRows(table, c);
283
+ } else {
284
+ if ( e > rows.length ) {
285
+ e = rows.length;
286
+ }
287
+ $(table.tBodies[0]).addClass('tablesorter-hidden');
288
+ $.tablesorter.clearTableBody(table);
289
+ for ( i = s; i < e; i++ ) {
290
+ o = rows[i];
291
+ l = o.length;
292
+ for ( j = 0; j < l; j++ ) {
293
+ f.appendChild(o[j]);
294
+ }
295
+ }
296
+ table.tBodies[0].appendChild(f);
297
+ $(table.tBodies[0]).removeClass('tablesorter-hidden');
298
+ }
299
+ if ( c.page >= c.totalPages ) {
300
+ moveToLastPage(table, c);
301
+ }
302
+ updatePageDisplay(table, c);
303
+ if ( !c.isDisabled ) { fixHeight(table, c); }
304
+ $(table).trigger('applyWidgets');
305
+ },
306
+
307
+ showAllRows = function(table, c){
308
+ if ( c.ajax ) {
309
+ pagerArrows(c, true);
310
+ } else {
311
+ c.isDisabled = true;
312
+ $.data(table, 'pagerLastPage', c.page);
313
+ $.data(table, 'pagerLastSize', c.size);
314
+ c.page = 0;
315
+ c.size = c.totalRows;
316
+ c.totalPages = 1;
317
+ $('tr.pagerSavedHeightSpacer', table.tBodies[0]).remove();
318
+ renderTable(table, table.config.rowsCopy, c);
319
+ }
320
+ // disable size selector
321
+ $(c.container).find(c.cssPageSize + ',' + c.cssGoto).each(function(){
322
+ $(this).addClass(c.cssDisabled)[0].disabled = true;
323
+ });
324
+ },
325
+
326
+ moveToPage = function(table, c) {
327
+ if ( c.isDisabled ) { return; }
328
+ var p = Math.min( c.totalPages, c.filteredPages );
329
+ if ( c.page < 0 || c.page > ( p - 1 ) ) {
330
+ c.page = 0;
331
+ }
332
+ // change if page changed - fixes #182
333
+ if (c.ajax && $.data(table, 'pagerLastPage') !== c.page) {
334
+ getAjax(table, c);
335
+ } else if (!c.ajax) {
336
+ renderTable(table, table.config.rowsCopy, c);
337
+ }
338
+ $.data(table, 'pagerLastPage', c.page);
339
+ if (c.initialized) { $(table).trigger('pageMoved', c); }
340
+ },
341
+
342
+ setPageSize = function(table, size, c) {
343
+ c.size = size;
344
+ $.data(table, 'pagerLastPage', c.page);
345
+ $.data(table, 'pagerLastSize', c.size);
346
+ c.totalPages = Math.ceil( c.totalRows / c.size );
347
+ moveToPage(table, c);
348
+ },
349
+
350
+ moveToFirstPage = function(table, c) {
351
+ c.page = 0;
352
+ moveToPage(table, c);
353
+ },
354
+
355
+ moveToLastPage = function(table, c) {
356
+ c.page = ( Math.min( c.totalPages, c.filteredPages ) - 1 );
357
+ moveToPage(table, c);
358
+ },
359
+
360
+ moveToNextPage = function(table, c) {
361
+ c.page++;
362
+ if ( c.page >= ( Math.min( c.totalPages, c.filteredPages ) - 1 ) ) {
363
+ c.page = ( Math.min( c.totalPages, c.filteredPages ) - 1 );
364
+ }
365
+ moveToPage(table, c);
366
+ },
367
+
368
+ moveToPrevPage = function(table, c) {
369
+ c.page--;
370
+ if ( c.page <= 0 ) {
371
+ c.page = 0;
372
+ }
373
+ moveToPage(table, c);
374
+ },
375
+
376
+ destroyPager = function(table, c){
377
+ showAllRows(table, c);
378
+ $(c.container).hide(); // hide pager
379
+ table.config.appender = null; // remove pager appender function
380
+ $(table).unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
381
+ },
382
+
383
+ enablePager = function(table, c, triggered){
384
+ var p = $(c.cssPageSize, c.container).removeClass(c.cssDisabled).removeAttr('disabled');
385
+ $(c.container).find(c.cssGoto).removeClass(c.cssDisabled).removeAttr('disabled');
386
+ c.isDisabled = false;
387
+ c.page = $.data(table, 'pagerLastPage') || c.page || 0;
388
+ c.size = $.data(table, 'pagerLastSize') || parseInt(p.find('option[selected]').val(), 10) || c.size;
389
+ p.val(c.size); // set page size
390
+ c.totalPages = Math.ceil( Math.min( c.totalPages, c.filteredPages ) / c.size);
391
+ if ( triggered ) {
392
+ $(table).trigger('update');
393
+ setPageSize(table, c.size, c);
394
+ hideRowsSetup(table, c);
395
+ fixHeight(table, c);
396
+ }
397
+ };
398
+
399
+ $this.appender = function(table, rows) {
400
+ var c = table.config.pager;
401
+ if ( !c.ajax ) {
402
+ table.config.rowsCopy = rows;
403
+ c.totalRows = rows.length;
404
+ c.size = $.data(table, 'pagerLastSize') || c.size;
405
+ c.totalPages = Math.ceil(c.totalRows / c.size);
406
+ renderTable(table, rows, c);
407
+ }
408
+ };
409
+
410
+ $this.construct = function(settings) {
411
+ return this.each(function() {
412
+ // check if tablesorter has initialized
413
+ if (!(this.config && this.hasInitialized)) { return; }
414
+ var config = this.config,
415
+ c = config.pager = $.extend( {}, $.tablesorterPager.defaults, settings ),
416
+ table = this,
417
+ $t = $(table),
418
+ pager = $(c.container).addClass('tablesorter-pager').show(); // added in case the pager is reinitialized after being destroyed.
419
+ config.appender = $this.appender;
420
+ // clear initialized flag
421
+ c.initialized = false;
422
+ enablePager(table, c, false);
423
+ if ( typeof(c.ajaxUrl) === 'string' ) {
424
+ // ajax pager; interact with database
425
+ c.ajax = true;
426
+ getAjax(table, c);
427
+ } else {
428
+ c.ajax = false;
429
+ // Regular pager; all rows stored in memory
430
+ $(this).trigger("appendCache", true);
431
+ hideRowsSetup(table, c);
432
+ }
433
+
434
+ // update pager after filter widget completes
435
+ $(table)
436
+ .unbind('filterEnd.pager updateComplete.pager ')
437
+ .bind('filterEnd.pager updateComplete.pager', function() {
438
+ if ($(this).hasClass('hasFilters')) {
439
+ c.page = 0;
440
+ updatePageDisplay(table, c);
441
+ moveToPage(table, c);
442
+ changeHeight(table, c);
443
+ }
444
+ });
445
+
446
+ if ( $(c.cssGoto, pager).length ) {
447
+ $(c.cssGoto, pager).bind('change', function(){
448
+ c.page = $(this).val() - 1;
449
+ moveToPage(table, c);
450
+ });
451
+ updatePageDisplay(table, c);
452
+ }
453
+ $(c.cssFirst,pager).unbind('click.pager').bind('click.pager', function() {
454
+ if ( !$(this).hasClass(c.cssDisabled) ) { moveToFirstPage(table, c); }
455
+ return false;
456
+ });
457
+ $(c.cssNext,pager).unbind('click.pager').bind('click.pager', function() {
458
+ if ( !$(this).hasClass(c.cssDisabled) ) { moveToNextPage(table, c); }
459
+ return false;
460
+ });
461
+ $(c.cssPrev,pager).unbind('click.pager').bind('click.pager', function() {
462
+ if ( !$(this).hasClass(c.cssDisabled) ) { moveToPrevPage(table, c); }
463
+ return false;
464
+ });
465
+ $(c.cssLast,pager).unbind('click.pager').bind('click.pager', function() {
466
+ if ( !$(this).hasClass(c.cssDisabled) ) { moveToLastPage(table, c); }
467
+ return false;
468
+ });
469
+ $(c.cssPageSize,pager).unbind('change.pager').bind('change.pager', function() {
470
+ $(c.cssPageSize,pager).val( $(this).val() ); // in case there are more than one pagers
471
+ if ( !$(this).hasClass(c.cssDisabled) ) {
472
+ setPageSize(table, parseInt( $(this).val(), 10 ), c);
473
+ changeHeight(table, c);
474
+ }
475
+ return false;
476
+ });
477
+
478
+ $t
479
+ .unbind('disable.pager enable.pager destroy.pager update.pager')
480
+ .bind('disable.pager', function(){
481
+ showAllRows(table, c);
482
+ })
483
+ .bind('enable.pager', function(){
484
+ enablePager(table, c, true);
485
+ })
486
+ .bind('destroy.pager', function(){
487
+ destroyPager(table, c);
488
+ })
489
+ .bind('update.pager', function(){
490
+ hideRows(table, c);
491
+ });
492
+
493
+ // pager initialized
494
+ if (!c.ajax) {
495
+ c.initialized = true;
496
+ $(table).trigger('pagerInitialized', c);
497
+ }
498
+ });
499
+ };
500
+
501
+ }()
502
+ });
503
+ // extend plugin scope
504
+ $.fn.extend({
505
+ tablesorterPager: $.tablesorterPager.construct
506
+ });
507
+
508
508
  })(jQuery);