jquery-tablesorter 1.18.5 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +1 -1
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +68 -46
  5. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +3 -3
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +2383 -2100
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +2298 -2039
  8. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +90 -66
  9. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-month.js +45 -20
  10. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-weekday.js +78 -20
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +37 -15
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +4 -4
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +2 -2
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +122 -30
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +8 -6
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +79 -58
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +209 -128
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js +5 -4
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-lazyload.js +367 -0
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +81 -35
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +3 -3
  22. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +79 -53
  23. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +25 -14
  24. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +5 -2
  25. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +11 -7
  26. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +149 -50
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sortTbodies.js +7 -7
  28. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +2 -2
  29. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +2 -2
  30. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-view.js +192 -0
  31. metadata +4 -2
@@ -1,4 +1,4 @@
1
- /*! Widget: math - updated 7/28/2015 (v2.22.4) *//*
1
+ /*! Widget: math - updated 10/31/2015 (v2.24.0) *//*
2
2
  * Requires tablesorter v2.16+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -18,11 +18,11 @@
18
18
  },
19
19
 
20
20
  // value returned when calculation is not possible, e.g. no values, dividing by zero, etc.
21
- invalid : function( name, errorIndex ) {
21
+ invalid : function( c, name, errorIndex ) {
22
22
  // name = function returning invalid results
23
23
  // errorIndex = math.error index with an explanation of the error
24
24
  console.log( name, math.error[ errorIndex ] );
25
- return 'none'; // text for cell
25
+ return c && c.widgetOptions.math_none || 'none'; // text for cell
26
26
  },
27
27
 
28
28
  events : ( 'tablesorter-initialized update updateAll updateRows addRows updateCell ' +
@@ -60,6 +60,7 @@
60
60
  var index, $t, len, $mathRows, mathAbove,
61
61
  arry = [],
62
62
  wo = c.widgetOptions,
63
+ mathAttr = wo.math_dataAttrib,
63
64
  filtered = wo.filter_filteredRow || 'filtered',
64
65
  cIndex = parseInt( $el.attr( 'data-column' ), 10 ),
65
66
  $rows = c.$table.children( 'tbody' ).children(),
@@ -71,10 +72,10 @@
71
72
  index = len;
72
73
  while ( index >= 0 ) {
73
74
  $t = $rows.eq( index ).children().filter( '[data-column=' + cIndex + ']' );
74
- mathAbove = $t.filter( '[' + wo.math_dataAttrib + '^=above]' ).length;
75
+ mathAbove = $t.filter( '[' + mathAttr + '^=above]' ).length;
75
76
  // ignore filtered rows & rows with data-math="ignore" (and starting row)
76
77
  if ( ( !$rows.eq( index ).hasClass( filtered ) &&
77
- $rows.eq( index ).not( '[' + wo.math_dataAttrib + '=ignore]' ).length &&
78
+ $rows.eq( index ).not( '[' + mathAttr + '=ignore]' ).length &&
78
79
  index !== len ) ||
79
80
  mathAbove && index !== len ) {
80
81
  // stop calculating 'above', when encountering another 'above'
@@ -86,13 +87,28 @@
86
87
  }
87
88
  index--;
88
89
  }
90
+ } else if ( type === 'below' ) {
91
+ len = $rows.length;
92
+ // index + 1 to ignore starting node
93
+ for ( index = $rows.index( $row ) + 1; index < len; index++ ) {
94
+ $t = $rows.eq( index ).children().filter( '[data-column=' + cIndex + ']' );
95
+ if ( $t.filter( '[' + mathAttr + '^=below]' ).length ) {
96
+ break;
97
+ }
98
+ if ( !$rows.eq( index ).hasClass( filtered ) &&
99
+ $rows.eq( index ).not( '[' + mathAttr + '=ignore]' ).length &&
100
+ $t.length ) {
101
+ arry.push( math.processText( c, $t ) );
102
+ }
103
+ }
104
+
89
105
  } else {
90
- $mathRows = $rows.not( '[' + wo.math_dataAttrib + '=ignore]' ); // .each(function(){
106
+ $mathRows = $rows.not( '[' + mathAttr + '=ignore]' );
91
107
  len = $mathRows.length;
92
108
  for ( index = 0; index < len; index++ ) {
93
109
  $t = $mathRows.eq( index ).children().filter( '[data-column=' + cIndex + ']' );
94
110
  if ( !$mathRows.eq( index ).hasClass( filtered ) &&
95
- $t.not( '[' + wo.math_dataAttrib + '^=above],[' + wo.math_dataAttrib + '^=col]' ).length &&
111
+ $t.not( '[' + mathAttr + '^=above],[' + mathAttr + '^=below],[' + mathAttr + '^=col]' ).length &&
96
112
  !$t.is( $el ) ) {
97
113
  arry.push( math.processText( c, $t ) );
98
114
  }
@@ -106,19 +122,20 @@
106
122
  var $t, col, $row, rowIndex, rowLen, $cells, cellIndex, cellLen,
107
123
  arry = [],
108
124
  wo = c.widgetOptions,
125
+ mathAttr = wo.math_dataAttrib,
109
126
  filtered = wo.filter_filteredRow || 'filtered',
110
- $rows = c.$table.children( 'tbody' ).children().not( '[' + wo.math_dataAttrib + '=ignore]' );
127
+ $rows = c.$table.children( 'tbody' ).children().not( '[' + mathAttr + '=ignore]' );
111
128
  rowLen = $rows.length;
112
129
  for ( rowIndex = 0; rowIndex < rowLen; rowIndex++ ) {
113
130
  $row = $rows.eq( rowIndex );
114
131
  if ( !$row.hasClass( filtered ) ) {
115
- $cells = $row.children().not( '[' + wo.math_dataAttrib + '=ignore]' );
132
+ $cells = $row.children().not( '[' + mathAttr + '=ignore]' );
116
133
  cellLen = $cells.length;
117
134
  // $row.children().each(function(){
118
135
  for ( cellIndex = 0; cellIndex < cellLen; cellIndex++ ) {
119
136
  $t = $cells.eq( cellIndex );
120
137
  col = parseInt( $t.attr( 'data-column' ), 10);
121
- if ( !$t.filter( '[' + wo.math_dataAttrib + ']' ).length && $.inArray( col, wo.math_ignore ) < 0 ) {
138
+ if ( !$t.filter( '[' + mathAttr + ']' ).length && $.inArray( col, wo.math_ignore ) < 0 ) {
122
139
  arry.push( math.processText( c, $t ) );
123
140
  }
124
141
  }
@@ -127,36 +144,58 @@
127
144
  return arry;
128
145
  },
129
146
 
147
+ setColumnIndexes : function( c ) {
148
+ c.$table.after( '<div id="_tablesorter_table_placeholder"></div>' );
149
+ // detach table from DOM to speed up column indexing
150
+ var $table = c.$table.detach();
151
+ ts.computeColumnIndex( $table.children( 'tbody' ).children() );
152
+ $( '#_tablesorter_table_placeholder' )
153
+ .after( $table )
154
+ .remove();
155
+ },
156
+
130
157
  recalculate : function(c, wo, init) {
131
158
  if ( c && ( !wo.math_isUpdating || init ) ) {
132
159
 
160
+ var time, mathAttr, $mathCells;
161
+ if ( c.debug ) {
162
+ time = new Date();
163
+ }
164
+
133
165
  // add data-column attributes to all table cells
134
166
  if ( init ) {
135
- ts.computeColumnIndex( c.$table.children( 'tbody' ).children() );
167
+ math.setColumnIndexes( c ) ;
136
168
  }
137
169
 
138
170
  // data-attribute name (defaults to data-math)
139
171
  wo.math_dataAttrib = 'data-' + (wo.math_data || 'math');
140
172
 
141
173
  // all non-info tbody cells
142
- var $mathCells = c.$tbodies.find( '[' + wo.math_dataAttrib + ']' );
174
+ mathAttr = wo.math_dataAttrib;
175
+ $mathCells = c.$tbodies.find( '[' + mathAttr + ']' );
143
176
  math.mathType( c, $mathCells, wo.math_priority );
144
177
 
145
178
  // only info tbody cells
146
179
  $mathCells = c.$table
147
180
  .children( '.' + c.cssInfoBlock + ', tfoot' )
148
- .find( '[' + wo.math_dataAttrib + ']' );
181
+ .find( '[' + mathAttr + ']' );
149
182
  math.mathType( c, $mathCells, wo.math_priority );
150
183
 
151
184
  // find the 'all' total
152
- $mathCells = c.$table.find( '[' + wo.math_dataAttrib + '^=all]' );
185
+ $mathCells = c.$table.find( '[' + mathAttr + '^=all]' );
153
186
  math.mathType( c, $mathCells, [ 'all' ] );
154
187
 
155
188
  wo.math_isUpdating = true;
156
189
  if ( c.debug ) {
157
190
  console[ console.group ? 'group' : 'log' ]( 'Math widget triggering an update after recalculation' );
158
191
  }
159
- c.$table.trigger( 'update' );
192
+
193
+ // update internal cache
194
+ ts.update( c );
195
+
196
+ if ( c.debug ) {
197
+ console.log( 'Math widget update completed' + ts.benchmark( time ) );
198
+ }
160
199
  }
161
200
  },
162
201
 
@@ -164,6 +203,7 @@
164
203
  if ( $cells.length ) {
165
204
  var formula, result, $el, arry, getAll, $targetCells, index, len,
166
205
  wo = c.widgetOptions,
206
+ mathAttr = wo.math_dataAttrib,
167
207
  equations = ts.equations;
168
208
  if ( priority[0] === 'all' ) {
169
209
  // no need to get all cells more than once
@@ -172,9 +212,9 @@
172
212
  if (c.debug) {
173
213
  console[ console.group ? 'group' : 'log' ]( 'Tablesorter Math widget recalculation' );
174
214
  }
175
- // $.each is okay here... only 3 priorities
215
+ // $.each is okay here... only 4 priorities
176
216
  $.each( priority, function( i, type ) {
177
- $targetCells = $cells.filter( '[' + wo.math_dataAttrib + '^=' + type + ']' );
217
+ $targetCells = $cells.filter( '[' + mathAttr + '^=' + type + ']' );
178
218
  len = $targetCells.length;
179
219
  if ( len ) {
180
220
  if (c.debug) {
@@ -182,18 +222,22 @@
182
222
  }
183
223
  for ( index = 0; index < len; index++ ) {
184
224
  $el = $targetCells.eq( index );
185
- formula = ( $el.attr( wo.math_dataAttrib ) || '' ).replace( type + '-', '' );
225
+ // Row is filtered, no need to do further checking
226
+ if ( $el.parent().hasClass( wo.filter_filteredRow || 'filtered' ) ) {
227
+ continue;
228
+ }
229
+ formula = ( $el.attr( mathAttr ) || '' ).replace( type + '-', '' );
186
230
  arry = ( type === 'row' ) ? math.getRow( c, $el ) :
187
231
  ( type === 'all' ) ? getAll : math.getColumn( c, $el, type );
188
232
  if ( equations[ formula ] ) {
189
233
  if ( arry.length ) {
190
- result = equations[ formula ]( arry );
234
+ result = equations[ formula ]( arry, c );
191
235
  if ( c.debug ) {
192
- console.log( $el.attr( wo.math_dataAttrib ), arry, '=', result );
236
+ console.log( $el.attr( mathAttr ), arry, '=', result );
193
237
  }
194
238
  } else {
195
239
  // mean will return a divide by zero error, everything else shows an undefined error
196
- result = math.invalid( formula, formula === 'mean' ? 0 : 'undef' );
240
+ result = math.invalid( c, formula, formula === 'mean' ? 0 : 'undef' );
197
241
  }
198
242
  math.output( $el, wo, result, arry );
199
243
  }
@@ -343,7 +387,7 @@
343
387
  var total = ts.equations.sum( arry );
344
388
  return total / arry.length;
345
389
  },
346
- median : function( arry ) {
390
+ median : function( arry, c ) {
347
391
  var half,
348
392
  len = arry.length;
349
393
  if ( len > 1 ) {
@@ -352,7 +396,7 @@
352
396
  half = Math.floor( len / 2 );
353
397
  return ( len % 2 ) ? arry[ half ] : ( arry[ half - 1 ] + arry[ half ] ) / 2;
354
398
  }
355
- return math.invalid( 'median', 1 );
399
+ return math.invalid( c, 'median', 1 );
356
400
  },
357
401
  mode : function( arry ) {
358
402
  // http://stackoverflow.com/a/3451640/145346
@@ -387,7 +431,7 @@
387
431
  },
388
432
  // common variance equation
389
433
  // (not accessible via data-attribute setting)
390
- variance: function( arry, population ) {
434
+ variance: function( arry, population, c ) {
391
435
  var divisor,
392
436
  avg = ts.equations.mean( arry ),
393
437
  v = 0,
@@ -397,27 +441,27 @@
397
441
  }
398
442
  divisor = ( arry.length - ( population ? 0 : 1 ) );
399
443
  if ( divisor === 0 ) {
400
- return math.invalid( 'variance', 0 );
444
+ return math.invalid( c, 'variance', 0 );
401
445
  }
402
446
  v /= divisor;
403
447
  return v;
404
448
  },
405
449
  // variance (population)
406
- varp : function( arry ) {
407
- return ts.equations.variance( arry, true );
450
+ varp : function( arry, c ) {
451
+ return ts.equations.variance( arry, true, c );
408
452
  },
409
453
  // variance (sample)
410
- vars : function( arry ) {
411
- return ts.equations.variance( arry );
454
+ vars : function( arry, c ) {
455
+ return ts.equations.variance( arry, false, c );
412
456
  },
413
457
  // standard deviation (sample)
414
- stdevs : function( arry ) {
415
- var vars = ts.equations.variance( arry );
458
+ stdevs : function( arry, c ) {
459
+ var vars = ts.equations.variance( arry, false, c );
416
460
  return Math.sqrt( vars );
417
461
  },
418
462
  // standard deviation (population)
419
- stdevp : function( arry ) {
420
- var varp = ts.equations.variance( arry, true );
463
+ stdevp : function( arry, c ) {
464
+ var varp = ts.equations.variance( arry, true, c );
421
465
  return Math.sqrt( varp );
422
466
  }
423
467
  };
@@ -436,11 +480,13 @@
436
480
  // complete executed after each fucntion
437
481
  math_complete : null, // function($cell, wo, result, value, arry){ return result; },
438
482
  // order of calculation; 'all' is last
439
- math_priority : [ 'row', 'above', 'col' ],
483
+ math_priority : [ 'row', 'above', 'below', 'col' ],
440
484
  // template for or just prepend the mask prefix & suffix with this HTML
441
485
  // e.g. '<span class="red">{content}</span>'
442
486
  math_prefix : '',
443
487
  math_suffix : '',
488
+ // no matching math elements found (text added to cell)
489
+ math_none : 'N/A',
444
490
  math_event : 'recalculate'
445
491
  },
446
492
  init : function( table, thisWidget, c, wo ) {
@@ -453,7 +499,7 @@
453
499
  if ( !wo.math_isUpdating || init ) {
454
500
  if ( !/filter/.test( e.type ) ) {
455
501
  // redo data-column indexes on update
456
- ts.computeColumnIndex( c.$table.children('tbody').children() );
502
+ math.setColumnIndexes( c ) ;
457
503
  }
458
504
  math.recalculate( c, wo, init );
459
505
  }
@@ -1,4 +1,4 @@
1
- /*! Widget: output - updated 7/28/2015 (v2.22.4) *//*
1
+ /*! Widget: output - updated 10/31/2015 (v2.24.0) *//*
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * Modified from:
4
4
  * HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
@@ -138,7 +138,7 @@
138
138
 
139
139
  // get header cells
140
140
  $this = $el
141
- .find('thead tr')
141
+ .children('thead').children('tr')
142
142
  .not('.' + (ts.css.filterRow || 'tablesorter-filter-row') )
143
143
  .filter( function() {
144
144
  return wo.output_hiddenColumns || $(this).css('display') !== 'none';
@@ -355,7 +355,7 @@
355
355
  output_popupStyle : 'width=500,height=300',
356
356
  output_saveFileName : 'mytable.csv',
357
357
  // format $cell content callback
358
- output_formatContent : null, // function(config, data){ return data.content; }
358
+ output_formatContent : null, // function(config, widgetOptions, data){ return data.content; }
359
359
  // callback executed when processing completes
360
360
  // return true to continue download/output
361
361
  // return false to stop delivery & do something else with the data
@@ -1,4 +1,4 @@
1
- /*! Widget: Pager - updated 10/4/2015 (v2.23.5) */
1
+ /*! Widget: Pager - updated 10/31/2015 (v2.24.0) */
2
2
  /* Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -129,7 +129,7 @@
129
129
 
130
130
  init: function(table) {
131
131
  // check if tablesorter has initialized
132
- if (table.hasInitialized && table.config.pager.initialized) { return; }
132
+ if (table.hasInitialized && table.config.pager && table.config.pager.initialized) { return; }
133
133
  var t,
134
134
  c = table.config,
135
135
  wo = c.widgetOptions,
@@ -171,7 +171,6 @@
171
171
  p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
172
172
  c.appender = tsp.appender;
173
173
  p.initializing = true;
174
- p.showAll = false;
175
174
  if (wo.pager_savePages && ts.storage) {
176
175
  t = ts.storage(table, wo.pager_storageKey) || {}; // fixes #387
177
176
  p.page = ( isNaN(t.page) ? p.page : t.page ) || p.setPage || 0;
@@ -203,7 +202,7 @@
203
202
  } else {
204
203
  p.ajax = false;
205
204
  // Regular pager; all rows stored in memory
206
- c.$table.trigger('appendCache', [ {}, true ]);
205
+ ts.appendCache( c, true ); // true = don't apply widgets
207
206
  }
208
207
 
209
208
  },
@@ -211,8 +210,7 @@
211
210
  initComplete: function(table, c){
212
211
  var p = c.pager;
213
212
  tsp.bindEvents(table, c);
214
- tsp.setPageSize(table, 0, c); // page size 0 is ignored
215
-
213
+ tsp.setPageSize(c, 0); // page size 0 is ignored
216
214
  if (!p.ajax) {
217
215
  tsp.hideRowsSetup(table, c);
218
216
  }
@@ -224,7 +222,7 @@
224
222
  if (c.debug) {
225
223
  console.log('Pager: Triggering pagerInitialized');
226
224
  }
227
- c.$table.trigger('pagerInitialized', c);
225
+ c.$table.trigger( 'pagerInitialized', c );
228
226
  // filter widget not initialized; it will update the output display & fire off the pagerComplete event
229
227
  if ( !( c.widgetOptions.filter_initialized && ts.hasWidget(table, 'filter') ) ) {
230
228
  // if ajax, then don't fire off pagerComplete
@@ -258,7 +256,7 @@
258
256
  }
259
257
  tsp.updatePageDisplay(table, c, false);
260
258
  // tsp.moveToPage(table, p, false); <-- called when applyWidgets is triggered
261
- c.$table.trigger('applyWidgets');
259
+ ts.applyWidget( table );
262
260
  }
263
261
  })
264
262
  .on('disablePager' + namespace, function(e){
@@ -271,7 +269,8 @@
271
269
  })
272
270
  .on('destroyPager' + namespace, function(e, refreshing){
273
271
  e.stopPropagation();
274
- tsp.destroyPager(table, c, refreshing);
272
+ // call removeWidget to make sure internal flags are modified.
273
+ ts.removeWidget( table, 'pager', false );
275
274
  })
276
275
  .on('updateComplete' + namespace, function(e, table, triggered){
277
276
  e.stopPropagation();
@@ -293,30 +292,30 @@
293
292
  // update without triggering pagerComplete
294
293
  tsp.updatePageDisplay(table, c, false);
295
294
  // make sure widgets are applied - fixes #450
296
- c.$table.trigger('applyWidgets');
295
+ ts.applyWidget( table );
297
296
  tsp.updatePageDisplay(table, c);
298
297
  })
299
- .on('pageSize refreshComplete '.split(' ').join(namespace + ' '), function(e, v){
298
+ .on('pageSize refreshComplete '.split(' ').join(namespace + ' '), function(e, size){
300
299
  e.stopPropagation();
301
- tsp.setPageSize(table, parseInt(v, 10) || p.setSize || 10, c);
300
+ tsp.setPageSize(c, tsp.parsePageSize( c, size, 'get' ));
302
301
  tsp.hideRows(table, c);
303
302
  tsp.updatePageDisplay(table, c, false);
304
303
  })
305
- .on('pageSet pagerUpdate '.split(' ').join(namespace + ' '), function(e, v){
304
+ .on('pageSet pagerUpdate '.split(' ').join(namespace + ' '), function(e, num){
306
305
  e.stopPropagation();
307
306
  // force pager refresh
308
307
  if (e.type === 'pagerUpdate') {
309
- v = typeof v === 'undefined' ? p.page + 1 : v;
308
+ num = typeof num === 'undefined' ? p.page + 1 : num;
310
309
  p.last.page = true;
311
310
  }
312
- p.page = (parseInt(v, 10) || 1) - 1;
311
+ p.page = (parseInt(num, 10) || 1) - 1;
313
312
  tsp.moveToPage(table, p, true);
314
313
  tsp.updatePageDisplay(table, c, false);
315
314
  })
316
315
  .on('pageAndSize' + namespace, function(e, page, size){
317
316
  e.stopPropagation();
318
317
  p.page = (parseInt(page, 10) || 1) - 1;
319
- tsp.setPageSize(table, parseInt(size, 10) || p.setSize || 10, c);
318
+ tsp.setPageSize(c, tsp.parsePageSize( c, size, 'get' ));
320
319
  tsp.moveToPage(table, p, true);
321
320
  tsp.hideRows(table, c);
322
321
  tsp.updatePageDisplay(table, c, false);
@@ -364,9 +363,10 @@
364
363
  p.$size
365
364
  .off('change' + namespace)
366
365
  .on('change' + namespace, function() {
367
- p.$size.val( $(this).val() ); // in case there are more than one pagers
368
366
  if ( !$(this).hasClass(wo.pager_css.disabled) ) {
369
- tsp.setPageSize(table, parseInt( $(this).val(), 10 ), c);
367
+ var size = $(this).val();
368
+ p.$size.val( size ); // in case there are more than one pagers
369
+ tsp.setPageSize(c, size);
370
370
  tsp.changeHeight(table, c);
371
371
  }
372
372
  return false;
@@ -420,11 +420,12 @@
420
420
  wo = c.widgetOptions,
421
421
  p = c.pager,
422
422
  namespace = c.namespace + 'pager',
423
- sz = p.size || p.setSize || 10; // don't allow dividing by zero
423
+ sz = tsp.parsePageSize( c, p.size, 'get' ); // don't allow dividing by zero
424
424
  if (wo.pager_countChildRows) { t.push(c.cssChildRow); }
425
425
  p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
426
426
  p.totalPages = Math.ceil( p.totalRows / sz ); // needed for 'pageSize' method
427
427
  c.totalRows = p.totalRows;
428
+ tsp.parsePageNumber( p );
428
429
  tsp.calcFilters(table, c);
429
430
  c.filteredRows = p.filteredRows;
430
431
  p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
@@ -634,8 +635,10 @@
634
635
 
635
636
  hideRowsSetup: function(table, c){
636
637
  var p = c.pager,
637
- namespace = c.namespace + 'pager';
638
- p.size = parseInt( p.$size.val(), 10 ) || p.size || p.setSize || 10;
638
+ namespace = c.namespace + 'pager',
639
+ size = p.$size.val();
640
+ p.size = tsp.parsePageSize( c, size, 'get' );
641
+ p.$size.val( tsp.parsePageSize( c, p.size, 'set' ) );
639
642
  $.data(table, 'pagerLastSize', p.size);
640
643
  tsp.pagerArrows(c);
641
644
  if ( !c.widgetOptions.pager_removeRows ) {
@@ -692,7 +695,7 @@
692
695
  if (d instanceof jQuery) {
693
696
  if (wo.pager_processAjaxOnInit) {
694
697
  // append jQuery object
695
- c.$tbodies.eq(0).children('tr').detach();
698
+ c.$tbodies.eq(0).empty();
696
699
  c.$tbodies.eq(0).append(d);
697
700
  }
698
701
  } else if (l) {
@@ -709,6 +712,9 @@
709
712
  if (wo.pager_processAjaxOnInit) {
710
713
  c.$tbodies.eq(0).html( tds );
711
714
  }
715
+ } else {
716
+ // nothing returned by ajax, empty out the table; see #1032
717
+ c.$tbodies.eq(0).empty();
712
718
  }
713
719
  wo.pager_processAjaxOnInit = true;
714
720
  // only add new header text if the length matches
@@ -744,14 +750,15 @@
744
750
  }
745
751
  // make sure last pager settings are saved, prevents multiple server side calls with
746
752
  // the same parameters
747
- p.totalPages = Math.ceil( p.totalRows / ( p.size || p.setSize || 10 ) );
753
+ p.totalPages = Math.ceil( p.totalRows / tsp.parsePageSize( c, p.size, 'get' ) );
748
754
  p.last.totalRows = p.totalRows;
749
755
  p.last.currentFilters = p.currentFilters;
750
756
  p.last.sortList = (c.sortList || []).join(',');
751
757
  p.initializing = false;
752
758
  // update display without triggering pager complete... before updating cache
753
759
  tsp.updatePageDisplay(table, c, false);
754
- $table.trigger('updateCache', [ function(){
760
+ // tablesorter core updateCache (not pager)
761
+ ts.updateCache( c, function(){
755
762
  if (p.initialized) {
756
763
  // apply widgets after table has rendered & after a delay to prevent
757
764
  // multiple applyWidget blocking code from blocking this trigger
@@ -759,16 +766,15 @@
759
766
  if (c.debug) {
760
767
  console.log('Pager: Triggering pagerChange');
761
768
  }
762
- $table
763
- .trigger('applyWidgets')
764
- .trigger('pagerChange', p);
769
+ $table.trigger( 'pagerChange', p );
770
+ ts.applyWidget( table );
765
771
  tsp.updatePageDisplay(table, c);
766
772
  }, 0);
767
773
  }
768
- } ]);
774
+ });
769
775
  }
770
776
  if (!p.initialized) {
771
- c.$table.trigger('applyWidgets');
777
+ ts.applyWidget( table );
772
778
  }
773
779
  },
774
780
 
@@ -877,9 +883,9 @@
877
883
  if (c.debug) {
878
884
  console.log('Pager: Triggering pagerChange');
879
885
  }
880
- c.$table.trigger('pagerChange', c);
886
+ c.$table.trigger( 'pagerChange', c );
881
887
  }
882
- if ( !wo.pager_removeRows && !p.showAll ) {
888
+ if ( !wo.pager_removeRows ) {
883
889
  tsp.hideRows(table, c);
884
890
  } else {
885
891
  ts.clearTableBody(table);
@@ -927,14 +933,13 @@
927
933
  p.page = 0;
928
934
  p.size = p.totalRows;
929
935
  p.totalPages = 1;
930
- p.showAll = true;
931
936
  c.$table
932
937
  .addClass('pagerDisabled')
933
938
  .removeAttr('aria-describedby')
934
939
  .find('tr.pagerSavedHeightSpacer').remove();
935
940
  tsp.renderTable(table, c.rowsCopy);
936
941
  p.isDisabled = true;
937
- c.$table.trigger('applyWidgets');
942
+ ts.applyWidget( table );
938
943
  if (c.debug) {
939
944
  console.log('Pager: Disabled');
940
945
  }
@@ -956,7 +961,8 @@
956
961
  updateCache: function(table) {
957
962
  var c = table.config,
958
963
  p = c.pager;
959
- c.$table.trigger('updateCache', [ function(){
964
+ // tablesorter core updateCache (not pager)
965
+ ts.updateCache( c, function(){
960
966
  if ( !$.isEmptyObject(table.config.cache) ) {
961
967
  var i,
962
968
  rows = [],
@@ -970,7 +976,7 @@
970
976
  // clear out last search to force an update
971
977
  p.last.currentFilters = [ ' ' ];
972
978
  }
973
- } ]);
979
+ });
974
980
  },
975
981
 
976
982
  moveToPage: function(table, p, pageMoved) {
@@ -978,17 +984,15 @@
978
984
  if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
979
985
  return tsp.updateCache(table);
980
986
  }
981
- var pg, c = table.config,
987
+ var c = table.config,
982
988
  wo = c.widgetOptions,
983
989
  l = p.last;
984
990
 
985
991
  // abort page move if the table has filters and has not been initialized
986
992
  if (p.ajax && !wo.filter_initialized && ts.hasWidget(table, 'filter')) { return; }
987
993
 
994
+ tsp.parsePageNumber( p );
988
995
  tsp.calcFilters(table, c);
989
- pg = Math.min( p.totalPages, p.filteredPages );
990
- if ( p.page < 0 ) { p.page = 0; }
991
- if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
992
996
 
993
997
  // fixes issue where one current filter is [] and the other is [ '', '', '' ],
994
998
  // making the next if comparison think the filters as different. Fixes #202.
@@ -1027,9 +1031,8 @@
1027
1031
  if (c.debug) {
1028
1032
  console.log('Pager: Triggering pageMoved');
1029
1033
  }
1030
- c.$table
1031
- .trigger('pageMoved', c)
1032
- .trigger('applyWidgets');
1034
+ c.$table.trigger('pageMoved', c);
1035
+ ts.applyWidget( table );
1033
1036
  if (!p.ajax && table.isUpdating) {
1034
1037
  if (c.debug) {
1035
1038
  console.log('Pager: Triggering updateComplete');
@@ -1039,11 +1042,32 @@
1039
1042
  }
1040
1043
  },
1041
1044
 
1042
- setPageSize: function(table, size, c) {
1043
- var p = c.pager;
1044
- p.size = size || p.size || p.setSize || 10;
1045
- p.$size.val(p.size);
1046
- $.data(table, 'pagerLastPage', p.page);
1045
+ // set to either set or get value
1046
+ parsePageSize: function( c, size, mode ) {
1047
+ var p = c.pager,
1048
+ s = parseInt( size, 10 ) || p.size || c.widgetOptions.pager_size || 10,
1049
+ // if select does not contain an "all" option, use size
1050
+ setAll = p.$size.find( 'option[value="all"]' ).length ? 'all' : p.totalRows;
1051
+ return /all/i.test( size ) || s === p.totalRows ?
1052
+ // "get" to set `p.size` or "set" to set `p.$size.val()`
1053
+ ( mode === 'get' ? p.totalRows : setAll ) :
1054
+ ( mode === 'get' ? s : p.size );
1055
+ },
1056
+
1057
+ parsePageNumber: function( p ) {
1058
+ var min = Math.min( p.totalPages, p.filteredPages ) - 1;
1059
+ p.page = parseInt( p.page, 10 );
1060
+ if ( p.page < 0 || isNaN( p.page ) ) { p.page = 0; }
1061
+ if ( p.page > min && p.page !== 0 ) { p.page = min; }
1062
+ return p.page;
1063
+ },
1064
+
1065
+ setPageSize: function(c, size) {
1066
+ var p = c.pager,
1067
+ table = c.table;
1068
+ p.size = tsp.parsePageSize( c, size, 'get' );
1069
+ p.$size.val( tsp.parsePageSize( c, p.size, 'set' ) );
1070
+ $.data(table, 'pagerLastPage', tsp.parsePageNumber( p ) );
1047
1071
  $.data(table, 'pagerLastSize', p.size);
1048
1072
  p.totalPages = Math.ceil( p.totalRows / p.size );
1049
1073
  p.filteredPages = Math.ceil( p.filteredRows / p.size );
@@ -1100,12 +1124,13 @@
1100
1124
  },
1101
1125
 
1102
1126
  enablePager: function(table, c, triggered){
1103
- var info, p = c.pager;
1127
+ var info, size,
1128
+ p = c.pager;
1104
1129
  p.isDisabled = false;
1105
- p.showAll = false;
1106
1130
  p.page = $.data(table, 'pagerLastPage') || p.page || 0;
1107
- p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || p.setSize || 10;
1108
- p.$size.val(p.size); // set page size
1131
+ size = p.$size.find('option[selected]').val();
1132
+ p.size = $.data(table, 'pagerLastSize') || tsp.parsePageSize( c, size, 'get' );
1133
+ p.$size.val( tsp.parsePageSize( c, p.size, 'set' ) ); // set page size
1109
1134
  p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
1110
1135
  c.$table.removeClass('pagerDisabled');
1111
1136
  // if table id exists, include page display with aria info
@@ -1116,8 +1141,9 @@
1116
1141
  }
1117
1142
  tsp.changeHeight(table, c);
1118
1143
  if ( triggered ) {
1119
- c.$table.trigger('updateRows');
1120
- tsp.setPageSize(table, p.size, c);
1144
+ // tablesorter core update table
1145
+ ts.update( c );
1146
+ tsp.setPageSize(c, p.size);
1121
1147
  tsp.hideRowsSetup(table, c);
1122
1148
  if (c.debug) {
1123
1149
  console.log('Pager: Enabled');