jquery-tablesorter 1.12.4 → 1.12.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b3086b10974536212d92994bb1a07c53305fb0d
4
- data.tar.gz: a8a53ba9dda00df5fda43382fd4996c4ef50d5cc
3
+ metadata.gz: d3a2967474752c48b4b2bcd5743672332758b852
4
+ data.tar.gz: e78a3ef07c01f2d563ee9df828b69ff6dec9d114
5
5
  SHA512:
6
- metadata.gz: 54887be0d4abdfba84a5c6c01b724a34756e95618369b6078a51dbaef6afa2edafb3ee5ed5f43cea7bf67941b732db7238c2f33f62a24a8cc18c679dd7ec52ac
7
- data.tar.gz: a51d74004a0ea5f3aa2fb7fe710d2f23665a5b846f0749eb3e36b232b696cbaaae150e31b8d5773d735fe2d3d56c787fda1f18328bf883bf5f9a1a82d2fe7101
6
+ metadata.gz: 7290bf0447e717080dd596016945d29db62e82d586c32ad329d0177eb2691ca979729bb162d31f7e707f24a181df2385febb1e26e5d5a7cc89f3c16e14683e09
7
+ data.tar.gz: 12387d4cfe2fa24a7ff2906002012a43afb7970fc91e432fa1caae5522e3206b3a41fb73e9acf612d526333039699ab683cc56eeb6bf01c3a5cffbc753989b9b
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Simple integration of jquery-tablesorter into the asset pipeline.
6
6
 
7
- Current tablesorter version: 2.17.4 (7/4/2014), [documentation]
7
+ Current tablesorter version: 2.17.5 (7/17/2014), [documentation]
8
8
 
9
9
  Any issue associated with the js/css files, please report to [Mottie's fork].
10
10
 
@@ -1,3 +1,3 @@
1
1
  module JqueryTablesorter
2
- VERSION = '1.12.4'
2
+ VERSION = '1.12.5'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * tablesorter pager plugin
3
- * updated 7/4/2014 (v2.17.4)
3
+ * updated 7/17/2014 (v2.17.5)
4
4
  */
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  ;(function($) {
@@ -137,15 +137,20 @@
137
137
  t = [ (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered'), c.selectorRemove.replace(/^(\w+\.)/g,'') ];
138
138
  if (p.countChildRows) { t.push(c.cssChildRow); }
139
139
  regex = new RegExp( '(' + t.join('|') + ')' );
140
- p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
141
140
  if (f && !p.ajaxUrl) {
142
- p.filteredRows = 0;
143
- $.each(c.cache[0].normalized, function(i, el) {
144
- p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
145
- });
141
+ if ($.isEmptyObject(c.cache)) {
142
+ // delayInit: true so nothing is in the cache
143
+ p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( p.countChildRows ? '' : '.' + c.cssChildRow ).length;
144
+ } else {
145
+ p.filteredRows = 0;
146
+ $.each(c.cache[0].normalized, function(i, el) {
147
+ p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
148
+ });
149
+ }
146
150
  } else if (!f) {
147
151
  p.filteredRows = p.totalRows;
148
152
  }
153
+ p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
149
154
  c.totalRows = p.totalRows;
150
155
  c.filteredRows = p.filteredRows;
151
156
  p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
@@ -292,7 +297,7 @@
292
297
  exception === 'timeout' ? 'Time out error' :
293
298
  exception === 'abort' ? 'Ajax Request aborted' :
294
299
  'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
295
- c.$tbodies.eq(0).children().detach();
300
+ c.$tbodies.eq(0).children('tr').detach();
296
301
  p.totalRows = 0;
297
302
  } else {
298
303
  // process ajax object
@@ -317,7 +322,7 @@
317
322
  if (d instanceof jQuery) {
318
323
  if (p.processAjaxOnInit) {
319
324
  // append jQuery object
320
- c.$tbodies.eq(0).children().detach();
325
+ c.$tbodies.eq(0).children('tr').detach();
321
326
  c.$tbodies.eq(0).append(d);
322
327
  }
323
328
  } else if (l) {
@@ -477,7 +482,13 @@
477
482
  l = rows && rows.length || 0, // rows may be undefined
478
483
  s = ( p.page * p.size ),
479
484
  e = p.size;
480
- if ( l < 1 ) { return; } // empty table, abort!
485
+ if ( l < 1 ) {
486
+ if (c.debug) {
487
+ ts.log('Pager: no rows for pager to render');
488
+ }
489
+ // empty table, abort!
490
+ return;
491
+ }
481
492
  if ( p.page >= p.totalPages ) {
482
493
  // lets not render the table more than once
483
494
  moveToLastPage(table, p);
@@ -540,12 +551,32 @@
540
551
  });
541
552
  },
542
553
 
554
+ // updateCache if delayInit: true
555
+ updateCache = function(table) {
556
+ var c = table.config,
557
+ p = c.pager;
558
+ c.$table.trigger('updateCache', [ function(){
559
+ var i,
560
+ rows = [],
561
+ n = table.config.cache[0].normalized;
562
+ p.totalRows = n.length;
563
+ for (i = 0; i < p.totalRows; i++) {
564
+ rows.push(n[i][c.columns].$row);
565
+ }
566
+ c.rowsCopy = rows;
567
+ moveToPage(table, p, true);
568
+ } ]);
569
+ },
570
+
543
571
  moveToPage = function(table, p, pageMoved) {
544
572
  if ( p.isDisabled ) { return; }
545
573
  var c = table.config,
546
574
  $t = $(table),
547
575
  l = p.last,
548
576
  pg = Math.min( p.totalPages, p.filteredPages );
577
+ if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
578
+ return updateCache(table);
579
+ }
549
580
  if ( p.page < 0 ) { p.page = 0; }
550
581
  if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
551
582
  // fixes issue where one currentFilter is [] and the other is ['','',''],
@@ -716,6 +747,10 @@
716
747
  // update pager after filter widget completes
717
748
  .bind('filterEnd.pager sortEnd.pager', function() {
718
749
  if (p.initialized) {
750
+ if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
751
+ // make sure we have a copy of all table rows once the cache has been built
752
+ updateCache(table);
753
+ }
719
754
  // update page display first, so we update p.filteredPages
720
755
  updatePageDisplay(table, p, false);
721
756
  moveToPage(table, p, false);
@@ -754,7 +789,7 @@
754
789
  e.stopPropagation();
755
790
  p.page = (parseInt(v, 10) || 1) - 1;
756
791
  if (p.$goto.length) { p.$goto.val(p.size); } // twice?
757
- moveToPage(table, p);
792
+ moveToPage(table, p, true);
758
793
  updatePageDisplay(table, p, false);
759
794
  });
760
795
 
@@ -784,7 +819,7 @@
784
819
  .unbind('change')
785
820
  .bind('change', function(){
786
821
  p.page = $(this).val() - 1;
787
- moveToPage(table, p);
822
+ moveToPage(table, p, true);
788
823
  updatePageDisplay(table, p, false);
789
824
  });
790
825
  }
@@ -1,5 +1,5 @@
1
1
  /**!
2
- * TableSorter 2.17.4 - Client-side table sorting with ease!
2
+ * TableSorter 2.17.5 - Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
5
5
  * Copyright (c) 2007 Christian Bach
@@ -24,7 +24,7 @@
24
24
 
25
25
  var ts = this;
26
26
 
27
- ts.version = "2.17.4";
27
+ ts.version = "2.17.5";
28
28
 
29
29
  ts.parsers = [];
30
30
  ts.widgets = [];
@@ -274,6 +274,7 @@
274
274
  $tb = c.$table.children('tbody'),
275
275
  parsers = c.parsers;
276
276
  c.cache = {};
277
+ c.totalRows = 0;
277
278
  // if no parsers found, return - it's an empty table.
278
279
  if (!parsers) {
279
280
  return c.debug ? log('Warning: *Empty table!* Not building a cache') : '';
@@ -343,6 +344,8 @@
343
344
  cc.normalized.push(cols);
344
345
  }
345
346
  cc.colMax = colMax;
347
+ // total up rows, not including child rows
348
+ c.totalRows += cc.normalized.length;
346
349
  }
347
350
  }
348
351
  if (c.showProcessing) {
@@ -1013,6 +1016,7 @@
1013
1016
  if (!/tablesorter\-/.test($table.attr('class'))) {
1014
1017
  k = (c.theme !== '' ? ' tablesorter-' + c.theme : '');
1015
1018
  }
1019
+ c.table = table;
1016
1020
  c.$table = $table
1017
1021
  .addClass(ts.css.table + ' ' + c.tableClass + k)
1018
1022
  .attr({ role : 'grid'});
@@ -1043,6 +1047,8 @@
1043
1047
  fixColumnWidth(table);
1044
1048
  // try to auto detect column type, and store in tables config
1045
1049
  buildParserCache(table);
1050
+ // start total row count at zero
1051
+ c.totalRows = 0;
1046
1052
  // build the cache for the tbody cells
1047
1053
  // delayInit will delay building the cache until the user starts a sort
1048
1054
  if (!c.delayInit) { buildCache(table); }
@@ -1534,13 +1540,14 @@
1534
1540
  $.each(widgets, function(i,w){
1535
1541
  if (w) {
1536
1542
  if (init || !(c.widgetInit[w.id])) {
1543
+ // set init flag first to prevent calling init more than once (e.g. pager)
1544
+ c.widgetInit[w.id] = true;
1537
1545
  if (w.hasOwnProperty('options')) {
1538
1546
  wo = table.config.widgetOptions = $.extend( true, {}, w.options, wo );
1539
1547
  }
1540
1548
  if (w.hasOwnProperty('init')) {
1541
1549
  w.init(table, w, c, wo);
1542
1550
  }
1543
- c.widgetInit[w.id] = true;
1544
1551
  }
1545
1552
  if (!init && w.hasOwnProperty('format')) {
1546
1553
  w.format(table, c, wo, false);
@@ -1,4 +1,4 @@
1
- /*! Filter widget formatter functions - updated 4/30/2014 (v2.16.3)
1
+ /*! Filter widget select2 formatter function - updated 7/17/2014 (v2.17.5)
2
2
  * requires: jQuery 1.7.2+, tableSorter 2.16+, filter widget 2.16+ and select2 v3.4.6+ plugin
3
3
  */
4
4
  /*jshint browser:true, jquery:true, unused:false */
@@ -102,6 +102,7 @@ ts.filterFormatter.select2 = function($cell, indx, select2Def) {
102
102
  val = val.replace(/[/()$^]/g, '').split('|');
103
103
  $cell.find('.select2').select2('val', val);
104
104
  updateSelect2();
105
+ ts.filter.formatterUpdated($cell, indx);
105
106
  });
106
107
 
107
108
  // has sticky headers?
@@ -1,4 +1,4 @@
1
- /*! Filter widget formatter functions - updated 6/18/2014 (v2.17.2)
1
+ /*! Filter widget formatter functions - updated 7/17/2014 (v2.17.5)
2
2
  * requires: tableSorter 2.15+ and jQuery 1.4.3+
3
3
  *
4
4
  * uiSpinner (jQuery UI spinner)
@@ -145,6 +145,7 @@ tsff = ts.filterFormatter = {
145
145
  var val = tsff.updateCompare($cell, $input, o)[0];
146
146
  $cell.find('.spinner').val( val );
147
147
  updateSpinner({ value: val }, true);
148
+ ts.filter.formatterUpdated($cell, indx);
148
149
  });
149
150
 
150
151
  if (o.compare) {
@@ -303,6 +304,7 @@ tsff = ts.filterFormatter = {
303
304
  var val = tsff.updateCompare($cell, $input, o)[0];
304
305
  $cell.find('.slider').slider('value', val );
305
306
  updateSlider({ value: val }, false);
307
+ ts.filter.formatterUpdated($cell, indx);
306
308
  });
307
309
 
308
310
  if (o.compare) {
@@ -447,6 +449,7 @@ tsff = ts.filterFormatter = {
447
449
  // update slider from hidden input, in case of saved filters
448
450
  c.$table.bind('filterFomatterUpdate', function(){
449
451
  getRange();
452
+ ts.filter.formatterUpdated($cell, indx);
450
453
  });
451
454
 
452
455
  // on reset
@@ -579,6 +582,7 @@ tsff = ts.filterFormatter = {
579
582
  $cell.add($shcell).find('.date').datepicker( 'setDate', num || null );
580
583
  setTimeout(function(){
581
584
  date1Compare(true);
585
+ ts.filter.formatterUpdated($cell, indx);
582
586
  }, 0);
583
587
  });
584
588
 
@@ -728,6 +732,7 @@ tsff = ts.filterFormatter = {
728
732
  // give datepicker time to process
729
733
  setTimeout(function(){
730
734
  closeDate();
735
+ ts.filter.formatterUpdated($cell, indx);
731
736
  }, 0);
732
737
  });
733
738
 
@@ -848,6 +853,7 @@ tsff = ts.filterFormatter = {
848
853
  var val = tsff.updateCompare($cell, $input, o)[0] || o.value;
849
854
  $cell.find('.number').val( ((val || '') + '').replace(/[><=]/g,'') );
850
855
  updateNumber(false, true);
856
+ ts.filter.formatterUpdated($cell, indx);
851
857
  });
852
858
 
853
859
  if (o.compare) {
@@ -968,6 +974,7 @@ tsff = ts.filterFormatter = {
968
974
  var val = tsff.updateCompare($cell, $input, o)[0];
969
975
  $cell.find('.range').val( val );
970
976
  updateRange(val, false, true);
977
+ ts.filter.formatterUpdated($cell, indx);
971
978
  });
972
979
 
973
980
  if (o.compare) {
@@ -1100,6 +1107,7 @@ tsff = ts.filterFormatter = {
1100
1107
  // update slider from hidden input, in case of saved filters
1101
1108
  c.$table.bind('filterFomatterUpdate', function(){
1102
1109
  updateColor( $input.val(), true );
1110
+ ts.filter.formatterUpdated($cell, indx);
1103
1111
  });
1104
1112
 
1105
1113
  // on reset
@@ -1,4 +1,4 @@
1
- /*! tableSorter 2.16+ widgets - updated 7/4/2014 (v2.17.4)
1
+ /*! tableSorter 2.16+ widgets - updated 7/17/2014 (v2.17.5)
2
2
  *
3
3
  * Column Styles
4
4
  * Column Filters
@@ -54,7 +54,6 @@ $.extend(ts.css, {
54
54
  filter : 'tablesorter-filter',
55
55
  wrapper : 'tablesorter-wrapper', // ui theme & resizable
56
56
  resizer : 'tablesorter-resizer', // resizable
57
- grip : 'tablesorter-resizer-grip',
58
57
  sticky : 'tablesorter-stickyHeader', // stickyHeader
59
58
  stickyVis : 'tablesorter-sticky-visible'
60
59
  });
@@ -444,7 +443,7 @@ ts.filter = {
444
443
  savedSearch = query;
445
444
  // parse filter value in case we're comparing numbers (dates)
446
445
  if (parsed[index] || parser.type === 'numeric') {
447
- result = parser.format( $.trim('' + iFilter.replace(ts.filter.regex.operators, '')), table, [], index );
446
+ result = ts.filter.parseFilter(table, $.trim('' + iFilter.replace(ts.filter.regex.operators, '')), index, parsed[index], true);
448
447
  query = ( typeof result === "number" && result !== '' && !isNaN(result) ) ? result : query;
449
448
  }
450
449
 
@@ -463,9 +462,9 @@ ts.filter = {
463
462
  return null;
464
463
  },
465
464
  // Look for a not match
466
- notMatch: function( filter, iFilter, exact, iExact, cached, index, table, wo ) {
465
+ notMatch: function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed ) {
467
466
  if ( /^\!/.test(iFilter) ) {
468
- iFilter = iFilter.replace('!', '');
467
+ iFilter = ts.filter.parseFilter(table, iFilter.replace('!', ''), index, parsed[index]);
469
468
  if (ts.filter.regex.exact.test(iFilter)) {
470
469
  // look for exact not matches - see #628
471
470
  iFilter = iFilter.replace(ts.filter.regex.exact, '');
@@ -481,19 +480,19 @@ ts.filter = {
481
480
  exact: function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed, rowArray ) {
482
481
  /*jshint eqeqeq:false */
483
482
  if (ts.filter.regex.exact.test(iFilter)) {
484
- var fltr = iFilter.replace(ts.filter.regex.exact, '');
483
+ var fltr = ts.filter.parseFilter(table, iFilter.replace(ts.filter.regex.exact, ''), index, parsed[index]);
485
484
  return rowArray ? $.inArray(fltr, rowArray) >= 0 : fltr == iExact;
486
485
  }
487
486
  return null;
488
487
  },
489
488
  // Look for an AND or && operator (logical and)
490
- and : function( filter, iFilter, exact, iExact ) {
489
+ and : function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed ) {
491
490
  if ( ts.filter.regex.andTest.test(filter) ) {
492
491
  var query = iFilter.split( ts.filter.regex.andSplit ),
493
- result = iExact.search( $.trim(query[0]) ) >= 0,
492
+ result = iExact.search( $.trim(ts.filter.parseFilter(table, query[0], index, parsed[index])) ) >= 0,
494
493
  indx = query.length - 1;
495
494
  while (result && indx) {
496
- result = result && iExact.search( $.trim(query[indx]) ) >= 0;
495
+ result = result && iExact.search( $.trim(ts.filter.parseFilter(table, query[indx], index, parsed[index])) ) >= 0;
497
496
  indx--;
498
497
  }
499
498
  return result;
@@ -507,8 +506,8 @@ ts.filter = {
507
506
  c = table.config,
508
507
  // make sure the dash is for a range and not indicating a negative number
509
508
  query = iFilter.split( ts.filter.regex.toSplit ),
510
- range1 = ts.formatFloat(query[0].replace(ts.filter.regex.nondigit, ''), table),
511
- range2 = ts.formatFloat(query[1].replace(ts.filter.regex.nondigit, ''), table);
509
+ range1 = ts.formatFloat( ts.filter.parseFilter(table, query[0].replace(ts.filter.regex.nondigit, ''), index, parsed[index]), table ),
510
+ range2 = ts.formatFloat( ts.filter.parseFilter(table, query[1].replace(ts.filter.regex.nondigit, ''), index, parsed[index]), table );
512
511
  // parse filter value in case we're comparing numbers (dates)
513
512
  if (parsed[index] || c.parsers[index].type === 'numeric') {
514
513
  result = c.parsers[index].format('' + query[0], table, c.$headers.eq(index), index);
@@ -528,22 +527,23 @@ ts.filter = {
528
527
  wild : function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed, rowArray ) {
529
528
  if ( /[\?|\*]/.test(iFilter) || ts.filter.regex.orReplace.test(filter) ) {
530
529
  var c = table.config,
531
- query = iFilter.replace(ts.filter.regex.orReplace, "|");
530
+ query = ts.filter.parseFilter(table, iFilter.replace(ts.filter.regex.orReplace, "|"), index, parsed[index]);
532
531
  // look for an exact match with the "or" unless the "filter-match" class is found
533
532
  if (!c.$headers.filter('[data-column="' + index + '"]:last').hasClass('filter-match') && /\|/.test(query)) {
534
533
  query = $.isArray(rowArray) ? '(' + query + ')' : '^(' + query + ')$';
535
534
  }
535
+ // parsing the filter may not work properly when using wildcards =/
536
536
  return new RegExp( query.replace(/\?/g, '\\S{1}').replace(/\*/g, '\\S*') ).test(iExact);
537
537
  }
538
538
  return null;
539
539
  },
540
540
  // fuzzy text search; modified from https://github.com/mattyork/fuzzy (MIT license)
541
- fuzzy: function( filter, iFilter, exact, iExact ) {
541
+ fuzzy: function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed ) {
542
542
  if ( /^~/.test(iFilter) ) {
543
543
  var indx,
544
544
  patternIndx = 0,
545
545
  len = iExact.length,
546
- pattern = iFilter.slice(1);
546
+ pattern = ts.filter.parseFilter(table, iFilter.slice(1), index, parsed[index]);
547
547
  for (indx = 0; indx < len; indx++) {
548
548
  if (iExact[indx] === pattern[patternIndx]) {
549
549
  patternIndx += 1;
@@ -572,8 +572,11 @@ ts.filter = {
572
572
  }
573
573
  c.$table.addClass('hasFilters');
574
574
 
575
- // define searchTimer so using clearTimeout won't cause an undefined error
575
+ // define timers so using clearTimeout won't cause an undefined error
576
576
  wo.searchTimer = null;
577
+ wo.filter_initTimer = null;
578
+ wo.filter_formatterCount = 0;
579
+ wo.filter_formatterInit = [];
577
580
 
578
581
  $.extend( regex, {
579
582
  child : new RegExp(c.cssChildRow),
@@ -593,7 +596,7 @@ ts.filter = {
593
596
  }
594
597
 
595
598
  c.$table.bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter '), function(event, filter) {
596
- c.$table.find('.' + ts.css.filterRow).toggle( !(wo.filter_hideEmpty && $.isEmptyObject(c.cache)) ); // fixes #450
599
+ c.$table.find('.' + ts.css.filterRow).toggle( !(wo.filter_hideEmpty && $.isEmptyObject(c.cache) && !(c.delayInit && event.type === 'appendCache')) ); // fixes #450
597
600
  if ( !/(search|filter)/.test(event.type) ) {
598
601
  event.stopPropagation();
599
602
  ts.filter.buildDefault(table, true);
@@ -681,6 +684,9 @@ ts.filter = {
681
684
  });
682
685
  }
683
686
 
687
+ // set filtered rows count (intially unfiltered)
688
+ c.filteredRows = c.totalRows;
689
+
684
690
  if (c.debug) {
685
691
  ts.benchmark("Applying Filter widget", time);
686
692
  }
@@ -690,24 +696,58 @@ ts.filter = {
690
696
  var wo = this.config.widgetOptions;
691
697
  filters = ts.filter.setDefaults(table, c, wo) || [];
692
698
  if (filters.length) {
693
- ts.setFilters(table, filters, true);
694
- // ts.filter.checkFilters(table, filters);
699
+ // prevent delayInit from triggering a cache build if filters are empty
700
+ if ( !(c.delayInit && filters.join('') === '') ) {
701
+ ts.setFilters(table, filters, true);
702
+ }
695
703
  }
696
704
  c.$table.trigger('filterFomatterUpdate');
697
- if (!wo.filter_initialized) {
698
- // filter widget initialized
699
- wo.filter_initialized = true;
700
- c.$table.trigger('filterInit', c);
701
- }
705
+ // trigger init after setTimeout to prevent multiple filterStart/End/Init triggers
706
+ setTimeout(function(){
707
+ if (!wo.filter_initialized) {
708
+ ts.filter.filterInitComplete(c);
709
+ }
710
+ }, 100);
702
711
  });
703
712
  // if filter widget is added after pager has initialized; then set filter init flag
704
713
  if (c.pager && c.pager.initialized && !wo.filter_initialized) {
714
+ c.$table.trigger('filterFomatterUpdate');
715
+ setTimeout(function(){
716
+ ts.filter.filterInitComplete(c);
717
+ }, 100);
718
+ }
719
+ },
720
+ // $cell parameter, but not the config, is passed to the
721
+ // filter_formatters, so we have to work with it instead
722
+ formatterUpdated: function($cell, column) {
723
+ var wo = $cell.closest('table')[0].config.widgetOptions;
724
+ if (!wo.filter_initialized) {
725
+ // add updates by column since this function
726
+ // may be called numerous times before initialization
727
+ wo.filter_formatterInit[column] = 1;
728
+ }
729
+ },
730
+ filterInitComplete: function(c){
731
+ var wo = c.widgetOptions,
732
+ count = 0;
733
+ $.each( wo.filter_formatterInit, function(i, val) {
734
+ if (val === 1) {
735
+ count++;
736
+ }
737
+ });
738
+ clearTimeout(wo.filter_initTimer);
739
+ if (!wo.filter_initialized && count === wo.filter_formatterCount) {
740
+ // filter widget initialized
705
741
  wo.filter_initialized = true;
706
- c.$table
707
- .trigger('filterFomatterUpdate')
708
- .trigger('filterInit', c);
742
+ c.$table.trigger('filterInit', c);
743
+ } else if (!wo.filter_initialized) {
744
+ // fall back in case a filter_formatter doesn't call
745
+ // $.tablesorter.filter.formatterUpdated($cell, column), and the count is off
746
+ wo.filter_initTimer = setTimeout(function(){
747
+ wo.filter_initialized = true;
748
+ c.$table.trigger('filterInit', c);
749
+ }, 500);
709
750
  }
710
-
711
751
  },
712
752
  setDefaults: function(table, c, wo) {
713
753
  var isArray, saved, indx,
@@ -728,6 +768,12 @@ ts.filter = {
728
768
  c.$table.data('lastSearch', filters);
729
769
  return filters;
730
770
  },
771
+ parseFilter: function(table, filter, column, parsed, forceParse){
772
+ var c = table.config;
773
+ return forceParse || parsed ?
774
+ c.parsers[column].format( filter, table, [], column ) :
775
+ filter;
776
+ },
731
777
  buildRow: function(table, c, wo) {
732
778
  var column, $header, buildSelect, disabled, name, ffxn,
733
779
  // c.columns defined in computeThIndexes()
@@ -753,6 +799,7 @@ ts.filter = {
753
799
  } else {
754
800
  ffxn = ts.getColumnData( table, wo.filter_formatter, column );
755
801
  if (ffxn) {
802
+ wo.filter_formatterCount++;
756
803
  buildFilter = ffxn( c.$filters.eq(column), column );
757
804
  // no element returned, so lets go find it
758
805
  if (buildFilter && buildFilter.length === 0) {
@@ -825,7 +872,9 @@ ts.filter = {
825
872
  ts.filter.searching( table, true, true );
826
873
  })
827
874
  .bind('search change keypress '.split(' ').join(c.namespace + 'filter '), function(event){
828
- if (event.which === 13 || event.type === 'search' || event.type === 'change') {
875
+ var column = $(this).data('column');
876
+ // don't allow "change" event to process if the input value is the same - fixes #685
877
+ if (event.which === 13 || event.type === 'search' || event.type === 'change' && this.value !== c.lastSearch[column]) {
829
878
  event.preventDefault();
830
879
  // init search with no delay
831
880
  $(this).attr('data-lastSearchTime', new Date().getTime());
@@ -853,7 +902,15 @@ ts.filter = {
853
902
  filters = (filterArray) ? filter : ts.getFilters(table, true),
854
903
  combinedFilters = (filters || []).join(''); // combined filter values
855
904
  // prevent errors if delay init is set
856
- if ($.isEmptyObject(c.cache)) { return; }
905
+ if ($.isEmptyObject(c.cache)) {
906
+ // update cache if delayInit set & pager has initialized (after user initiates a search)
907
+ if (c.delayInit && c.pager && c.pager.initialized) {
908
+ c.$table.trigger('updateCache', [function(){
909
+ ts.filter.checkFilters(table, false, skipFirst);
910
+ }] );
911
+ }
912
+ return;
913
+ }
857
914
  // add filter array back into inputs
858
915
  if (filterArray) {
859
916
  ts.setFilters( table, filters, false, skipFirst !== true );
@@ -1092,7 +1149,7 @@ ts.filter = {
1092
1149
  result = filterMatched;
1093
1150
  // Look for match, and add child row data for matching
1094
1151
  } else {
1095
- exact = (iExact + childRowText).indexOf(iFilter);
1152
+ exact = (iExact + childRowText).indexOf( ts.filter.parseFilter(table, iFilter, columnIndex, parsed[columnIndex]) );
1096
1153
  result = ( (!wo.filter_startsWith && exact >= 0) || (wo.filter_startsWith && exact === 0) );
1097
1154
  }
1098
1155
  }
@@ -1208,7 +1265,7 @@ ts.filter = {
1208
1265
  // check if has class filtered
1209
1266
  if (onlyAvail && row.className.match(wo.filter_filteredRow)) { continue; }
1210
1267
  // get non-normalized cell content
1211
- if (wo.filter_useParsedData) {
1268
+ if (wo.filter_useParsedData || c.parsers[column].parsed || c.$headers.filter('[data-column="' + column + '"]:last').hasClass('filter-parsed')) {
1212
1269
  arry.push( '' + cache.normalized[rowIndex][column] );
1213
1270
  } else {
1214
1271
  cell = row.cells[column];
@@ -1579,13 +1636,13 @@ ts.addWidget({
1579
1636
  $columns
1580
1637
  .each(function() {
1581
1638
  var $column = $(this),
1582
- padding = parseInt($column.css('padding-right'), 10) + 10; // 10 is 1/2 of the 20px wide resizer grip
1639
+ padding = parseInt($column.css('padding-right'), 10) + 10; // 10 is 1/2 of the 20px wide resizer
1583
1640
  $column
1584
1641
  .find('.' + ts.css.wrapper)
1585
1642
  .append('<div class="' + ts.css.resizer + '" style="cursor:w-resize;position:absolute;z-index:1;right:-' +
1586
1643
  padding + 'px;top:0;height:100%;width:20px;"></div>');
1587
1644
  })
1588
- .find('.' + ts.css.resizer + ',.' + ts.css.grip)
1645
+ .find('.' + ts.css.resizer)
1589
1646
  .bind('mousedown', function(event) {
1590
1647
  // save header cell and mouse position
1591
1648
  $target = $(event.target).closest('th');
@@ -1629,7 +1686,7 @@ ts.addWidget({
1629
1686
  .children('tr').children()
1630
1687
  .unbind('mousemove.tsresize mouseup.tsresize')
1631
1688
  // don't remove "tablesorter-wrapper" as uitheme uses it too
1632
- .find('.' + ts.css.resizer + ',.' + ts.css.grip).remove();
1689
+ .find('.' + ts.css.resizer).remove();
1633
1690
  ts.resizableReset(table);
1634
1691
  }
1635
1692
  });
@@ -0,0 +1,20 @@
1
+ /*! image alt attribute parser for jQuery 1.7+ & tablesorter 2.7.11+
2
+ * New 7/17/2014 (v2.17.5)
3
+ */
4
+ /*jshint jquery:true, unused:false */
5
+ ;(function($){
6
+ "use strict";
7
+
8
+ $.tablesorter.addParser({
9
+ id: "image",
10
+ is: function(){
11
+ return false;
12
+ },
13
+ format: function(s, table, cell) {
14
+ return $(cell).find('img').attr(table.config.imgAttr || 'alt') || s;
15
+ },
16
+ parsed : true, // filter widget flag
17
+ type: "text"
18
+ });
19
+
20
+ })(jQuery);
@@ -1,5 +1,5 @@
1
1
  /*! input & select parsers for jQuery 1.7+ & tablesorter 2.7.11+
2
- * Updated 5/28/2014 (v2.17.1)
2
+ * Updated 7/17/2014 (v2.17.5)
3
3
  * Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html
4
4
  */
5
5
  /*jshint browser: true, jquery:true, unused:false */
@@ -64,34 +64,50 @@
64
64
  type: "text"
65
65
  });
66
66
 
67
+ // Select parser to get the selected text
68
+ $.tablesorter.addParser({
69
+ id: "select-text",
70
+ is: function(){
71
+ return false;
72
+ },
73
+ format: function(s, table, cell) {
74
+ var $s = $(cell).find('select');
75
+ return $s.length ? $s.find('option:selected').text() || '' : s;
76
+ },
77
+ parsed : true, // filter widget flag
78
+ type: "text"
79
+ });
80
+
67
81
  // update select and all input types in the tablesorter cache when the change event fires.
68
82
  // This method only works with jQuery 1.7+
69
83
  // you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired
70
84
  // if this code interferes somehow, target the specific table $('#mytable'), instead of $('table')
71
- $(window).load(function(){
72
- // this flag prevents the updateCell event from being spammed
73
- // it happens when you modify input text and hit enter
74
- var alreadyUpdating = false,
75
- t = $.tablesorter.css.table || 'tablesorter';
76
- // bind to .tablesorter (default class name)
77
- $('.' + t).find('tbody').on('change', 'select, input', function(e){
78
- if (!alreadyUpdating) {
79
- var $tar = $(e.target),
80
- $cell = $tar.closest('td'),
81
- $table = $cell.closest('table'),
82
- indx = $cell[0].cellIndex,
83
- c = $table[0].config || false,
84
- $hdr = c && c.$headers && c.$headers.eq(indx);
85
- // abort if not a tablesorter table, or
86
- // don't use updateCell if column is set to "sorter-false" and "filter-false", or column is set to "parser-false"
87
- if ( !c || ( $hdr && $hdr.length && ( $hdr.hasClass('parser-false') || ($hdr.hasClass('sorter-false') && $hdr.hasClass('filter-false')) ) ) ){
88
- return false;
85
+ $(function(){
86
+ $('table').on('tablesorter-initialized', function(){
87
+ // this flag prevents the updateCell event from being spammed
88
+ // it happens when you modify input text and hit enter
89
+ var alreadyUpdating = false;
90
+ // bind to .tablesorter (default class name)
91
+ $(this).children('tbody').on('change', 'select, input', function(e){
92
+ if (!alreadyUpdating) {
93
+ var $tar = $(e.target),
94
+ $cell = $tar.closest('td'),
95
+ $table = $cell.closest('table'),
96
+ indx = $cell[0].cellIndex,
97
+ c = $table[0].config || false,
98
+ $hdr = c && c.$headers && c.$headers.eq(indx);
99
+ // abort if not a tablesorter table, or
100
+ // don't use updateCell if column is set to "sorter-false" and "filter-false", or column is set to "parser-false"
101
+ if ( !c || ( $hdr && $hdr.length && ( $hdr.hasClass('parser-false') || ($hdr.hasClass('sorter-false') && $hdr.hasClass('filter-false')) ) ) ){
102
+ return false;
103
+ }
104
+ alreadyUpdating = true;
105
+ $table.trigger('updateCell', [ $tar.closest('td'), resort, function(){
106
+ updateServer(e, $table, $tar);
107
+ setTimeout(function(){ alreadyUpdating = false; }, 10);
108
+ } ]);
89
109
  }
90
- alreadyUpdating = true;
91
- $table.trigger('updateCell', [ $tar.closest('td'), resort ]);
92
- updateServer(e, $table, $tar);
93
- setTimeout(function(){ alreadyUpdating = false; }, 10);
94
- }
110
+ });
95
111
  });
96
112
  });
97
113
 
@@ -1,4 +1,4 @@
1
- /* Output widget (beta) for TableSorter 5/22/2014 (v2.17.0)
1
+ /* Output widget (beta) for TableSorter 7/17/2014 (v2.17.5)
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?)
@@ -221,33 +221,55 @@ output = ts.output = {
221
221
  },
222
222
 
223
223
  // modified from https://github.com/PixelsCommander/Download-File-JS
224
+ // & http://html5-demos.appspot.com/static/a.download.html
224
225
  download : function (wo, data){
225
- var e, link,
226
- processedData = wo.output_encoding + encodeURIComponent(data);
226
+
227
+ var e, blob, gotBlob,
228
+ nav = window.navigator,
229
+ link = document.createElement('a');
227
230
 
228
231
  // iOS devices do not support downloading. We have to inform user about this.
229
- if (/(iP)/g.test(navigator.userAgent)) {
232
+ if (/(iP)/g.test(nav.userAgent)) {
230
233
  alert(output.message);
231
234
  return false;
232
235
  }
233
- // If in Chrome or Safari - download via virtual link click
234
- if ( /(chrome|safari)/.test(navigator.userAgent.toLowerCase()) ) {
235
- // Creating new link node.
236
- link = document.createElement('a');
237
- link.href = processedData;
238
- link.download = wo.output_saveFileName;
239
- // Dispatching click event.
240
- if (document.createEvent) {
241
- e = document.createEvent('MouseEvents');
242
- e.initEvent('click', true, true);
243
- link.dispatchEvent(e);
244
- return true;
236
+
237
+ // test for blob support
238
+ try {
239
+ gotBlob = !!new Blob();
240
+ } catch (err) {
241
+ gotBlob = false;
242
+ }
243
+
244
+ // Use HTML5 Blob if browser supports it
245
+ if ( gotBlob ) {
246
+
247
+ window.URL = window.webkitURL || window.URL;
248
+ blob = new Blob([data], {type: wo.output_encoding});
249
+
250
+ if (nav.msSaveBlob) {
251
+ // IE 10+
252
+ nav.msSaveBlob(blob, wo.output_saveFileName);
253
+ } else {
254
+ // all other browsers
255
+ link.href = window.URL.createObjectURL(blob);
256
+ link.download = wo.output_saveFileName;
257
+ // Dispatching click event; using $(link).trigger() won't work
258
+ if (document.createEvent) {
259
+ e = document.createEvent('MouseEvents');
260
+ // event.initMouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
261
+ e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
262
+ link.dispatchEvent(e);
263
+ }
245
264
  }
265
+ return false;
246
266
  }
247
- // Force file download (whether supported by server).
248
- processedData += '?download';
249
- window.open(processedData, '_self');
267
+
268
+ // fallback to force file download (whether supported by server).
269
+ // not sure if this actually works in IE9 and older...
270
+ window.open( wo.output_encoding + encodeURIComponent(data) + '?download' , '_self');
250
271
  return true;
272
+
251
273
  },
252
274
 
253
275
  remove : function(c) {
@@ -278,11 +300,9 @@ ts.addWidget({
278
300
  output_callback : function(config, data){ return true; },
279
301
  // JSON callback executed when a colspan is encountered in the header
280
302
  output_callbackJSON : function($cell, txt, cellIndex) { return txt + '(' + (cellIndex) + ')'; },
281
- // output data type (with BOM or Windows-1252 is needed for excel)
282
- // NO BOM : 'data:text/csv;charset=utf8,'
283
- // With BOM : 'data:text/csv;charset=utf8,%EF%BB%BF'
284
- // WIN 1252 : 'data:text/csv;charset=windows-1252'
285
- output_encoding : 'data:text/csv;charset=utf8,'
303
+ // the need to modify this for Excel no longer exists
304
+ output_encoding : 'data:application/octet-stream;charset=utf8,'
305
+
286
306
  },
287
307
  init: function(table, thisWidget, c) {
288
308
  output.init(c);
@@ -1,4 +1,4 @@
1
- /* Pager widget for TableSorter 7/4/2014 (v2.17.4) */
1
+ /* Pager widget for TableSorter 7/17/2014 (v2.17.5) */
2
2
  /*jshint browser:true, jquery:true, unused:false */
3
3
  ;(function($){
4
4
  "use strict";
@@ -153,7 +153,7 @@ tsp = ts.pager = {
153
153
  p.$goto = p.$container.find(s.gotoPage); // goto is a reserved word #657
154
154
  // page size selector
155
155
  p.$size = p.$container.find(s.pageSize);
156
- p.totalRows = c.$tbodies.eq(0).children('tr').length;
156
+ p.totalRows = c.$tbodies.eq(0).children('tr').not( c.widgetOptions.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
157
157
  p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
158
158
  c.appender = tsp.appender;
159
159
  if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
@@ -199,11 +199,11 @@ tsp = ts.pager = {
199
199
  var p = c.pager;
200
200
  tsp.changeHeight(table, c);
201
201
  tsp.bindEvents(table, c);
202
+ tsp.setPageSize(table, 0, c); // page size 0 is ignored
202
203
 
203
204
  // pager initialized
204
205
  p.initialized = true;
205
206
  p.isInitializing = false;
206
- tsp.setPageSize(table, 0, c); // page size 0 is ignored
207
207
  c.$table.trigger('pagerInitialized', c);
208
208
  tsp.updatePageDisplay(table, c);
209
209
  },
@@ -226,6 +226,10 @@ tsp = ts.pager = {
226
226
  // update pager after filter widget completes
227
227
  .bind('filterEnd.pager sortEnd.pager', function() {
228
228
  if (p.initialized) {
229
+ if (c.delayInit && c.rowsCopy && c.rowsCopy.length === 0) {
230
+ // make sure we have a copy of all table rows once the cache has been built
231
+ tsp.updateCache(table);
232
+ }
229
233
  // update page display first, so we update p.filteredPages
230
234
  tsp.updatePageDisplay(table, c, false);
231
235
  tsp.moveToPage(table, p, false);
@@ -266,7 +270,7 @@ tsp = ts.pager = {
266
270
  e.stopPropagation();
267
271
  p.page = (parseInt(v, 10) || 1) - 1;
268
272
  if (p.$goto.length) { p.$goto.val(c.size); } // twice?
269
- tsp.moveToPage(table, p);
273
+ tsp.moveToPage(table, p, true);
270
274
  tsp.updatePageDisplay(table, c, false);
271
275
  });
272
276
 
@@ -296,7 +300,7 @@ tsp = ts.pager = {
296
300
  .unbind('change')
297
301
  .bind('change', function(){
298
302
  p.page = $(this).val() - 1;
299
- tsp.moveToPage(table, p);
303
+ tsp.moveToPage(table, p, true);
300
304
  tsp.updatePageDisplay(table, c, false);
301
305
  });
302
306
  }
@@ -342,15 +346,20 @@ tsp = ts.pager = {
342
346
  if (wo.pager_countChildRows) { t.push(c.cssChildRow); }
343
347
  regex = new RegExp( '(' + t.join('|') + ')' );
344
348
  p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
345
- p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
346
349
  if (f && !wo.pager_ajaxUrl) {
347
- p.filteredRows = 0;
348
- $.each(c.cache[0].normalized, function(i, el) {
349
- p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
350
- });
350
+ if ($.isEmptyObject(c.cache)) {
351
+ // delayInit: true so nothing is in the cache
352
+ p.filteredRows = p.totalRows = c.$tbodies.eq(0).children('tr').not( c.widgetOptions.pager_countChildRows ? '' : '.' + c.cssChildRow ).length;
353
+ } else {
354
+ p.filteredRows = 0;
355
+ $.each(c.cache[0].normalized, function(i, el) {
356
+ p.filteredRows += p.regexRows.test(el[c.columns].$row[0].className) ? 0 : 1;
357
+ });
358
+ }
351
359
  } else if (!f) {
352
360
  p.filteredRows = p.totalRows;
353
361
  }
362
+ p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
354
363
  c.totalRows = p.totalRows;
355
364
  c.filteredRows = p.filteredRows;
356
365
  p.filteredPages = Math.ceil( p.filteredRows / sz ) || 0;
@@ -494,7 +503,7 @@ tsp = ts.pager = {
494
503
  ts.log('Ajax Error', xhr, exception);
495
504
  }
496
505
  ts.showError(table, exception.message + ' (' + xhr.status + ')');
497
- c.$tbodies.eq(0).children().detach();
506
+ c.$tbodies.eq(0).children('tr').detach();
498
507
  p.totalRows = 0;
499
508
  } else {
500
509
  // process ajax object
@@ -519,7 +528,7 @@ tsp = ts.pager = {
519
528
  if (d instanceof jQuery) {
520
529
  if (wo.pager_processAjaxOnInit) {
521
530
  // append jQuery object
522
- c.$tbodies.eq(0).children().detach();
531
+ c.$tbodies.eq(0).children('tr').detach();
523
532
  c.$tbodies.eq(0).append(d);
524
533
  }
525
534
  } else if (l) {
@@ -676,14 +685,19 @@ tsp = ts.pager = {
676
685
  l = rows && rows.length || 0, // rows may be undefined
677
686
  s = ( p.page * p.size ),
678
687
  e = p.size;
679
- if ( l < 1 ) { return; } // empty table, abort!
688
+ if ( l < 1 ) {
689
+ if (c.debug) {
690
+ ts.log('Pager: no rows for pager to render');
691
+ }
692
+ // empty table, abort!
693
+ return;
694
+ }
680
695
  if ( p.page >= p.totalPages ) {
681
696
  // lets not render the table more than once
682
697
  return tsp.moveToLastPage(table, p);
683
698
  }
684
699
  p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
685
700
  if (p.initialized) { c.$table.trigger('pagerChange', c); }
686
-
687
701
  if ( !wo.pager_removeRows ) {
688
702
  tsp.hideRows(table, c);
689
703
  } else {
@@ -746,8 +760,33 @@ tsp = ts.pager = {
746
760
  });
747
761
  },
748
762
 
763
+ // updateCache if delayInit: true
764
+ // this is normally done by "appendToTable" function in the tablesorter core AFTER a sort
765
+ updateCache: function(table) {
766
+ var c = table.config,
767
+ p = c.pager;
768
+ c.$table.trigger('updateCache', [ function(){
769
+ if ( !$.isEmptyObject(table.config.cache) ) {
770
+ var i,
771
+ rows = [],
772
+ n = table.config.cache[0].normalized;
773
+ p.totalRows = n.length;
774
+ for (i = 0; i < p.totalRows; i++) {
775
+ rows.push(n[i][c.columns].$row);
776
+ }
777
+ c.rowsCopy = rows;
778
+ tsp.moveToPage(table, p, true);
779
+ // clear out last search to force an update
780
+ p.last.currentFilters = [' '];
781
+ }
782
+ } ]);
783
+ },
784
+
749
785
  moveToPage: function(table, p, pageMoved) {
750
786
  if ( p.isDisabled ) { return; }
787
+ if ( pageMoved !== false && p.initialized && $.isEmptyObject(table.config.cache)) {
788
+ return tsp.updateCache(table);
789
+ }
751
790
  var c = table.config,
752
791
  l = p.last,
753
792
  pg = Math.min( p.totalPages, p.filteredPages );
@@ -796,17 +835,17 @@ tsp = ts.pager = {
796
835
  $.data(table, 'pagerLastSize', p.size);
797
836
  p.totalPages = Math.ceil( p.totalRows / p.size );
798
837
  p.filteredPages = Math.ceil( p.filteredRows / p.size );
799
- tsp.moveToPage(table, p);
838
+ tsp.moveToPage(table, p, true);
800
839
  },
801
840
 
802
841
  moveToFirstPage: function(table, p) {
803
842
  p.page = 0;
804
- tsp.moveToPage(table, p);
843
+ tsp.moveToPage(table, p, true);
805
844
  },
806
845
 
807
846
  moveToLastPage: function(table, p) {
808
847
  p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
809
- tsp.moveToPage(table, p);
848
+ tsp.moveToPage(table, p, true);
810
849
  },
811
850
 
812
851
  moveToNextPage: function(table, p) {
@@ -814,7 +853,7 @@ tsp = ts.pager = {
814
853
  if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
815
854
  p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
816
855
  }
817
- tsp.moveToPage(table, p);
856
+ tsp.moveToPage(table, p, true);
818
857
  },
819
858
 
820
859
  moveToPrevPage: function(table, p) {
@@ -822,7 +861,7 @@ tsp = ts.pager = {
822
861
  if ( p.page <= 0 ) {
823
862
  p.page = 0;
824
863
  }
825
- tsp.moveToPage(table, p);
864
+ tsp.moveToPage(table, p, true);
826
865
  },
827
866
 
828
867
  destroyPager: function(table, c){
@@ -872,7 +911,7 @@ tsp = ts.pager = {
872
911
  p.totalRows = c.widgetOptions.pager_countChildRows ? c.$tbodies.eq(0).children('tr').length : rows.length;
873
912
  p.size = $.data(table, 'pagerLastSize') || p.size || wo.pager_size || 10;
874
913
  p.totalPages = Math.ceil( p.totalRows / p.size );
875
- tsp.moveToPage(table, p, true);
914
+ tsp.moveToPage(table, p);
876
915
  // update display here in case all rows are removed
877
916
  tsp.updatePageDisplay(table, c, false);
878
917
  } else {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jquery-tablesorter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.4
4
+ version: 1.12.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jun Lin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-06 00:00:00.000000000 Z
12
+ date: 2014-07-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -93,6 +93,7 @@ files:
93
93
  - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-feet-inch-fraction.js
94
94
  - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-file-type.js
95
95
  - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-ignore-articles.js
96
+ - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-image.js
96
97
  - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js
97
98
  - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-ipv6.js
98
99
  - vendor/assets/javascripts/jquery-tablesorter/parsers/parser-metric.js