jquery-tablesorter 1.10.3 → 1.10.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3456e75e9e3f482d435a7b087e423988098e8a42
4
- data.tar.gz: cc5c3cf899555624f971b133145d3bbe46313706
3
+ metadata.gz: 4e9c4b55e83f583df24a50e72e50dd3193625600
4
+ data.tar.gz: 2242d68bf7499163fd6f4839b673655f703e9df8
5
5
  SHA512:
6
- metadata.gz: 34d92b0bc41faedffd68c7a9e01cb76ff96d325e65286db9d722eb98b7b9a4789c89be0d5df54796d5e0811b3bff97f4bda09ce841cfcd47caa6c895f6d9ef07
7
- data.tar.gz: 93ae0f842b189cc55cd2240f1512ac508b6a53dddc6c6435ea333e16d6fb881a2a3b6c1f006943234fd2e607231e476564e4a41715a90e2f5385e09231ed7793
6
+ metadata.gz: 53eba97a412635392168b9375f97cd76ec45cc0e1c056ad3a07a17bde3fda060724577b03b0b1e923944aa441a674dabc4c37f01c295050819d74a0fd90fb3bf
7
+ data.tar.gz: 702b8fb3e5342484899fa7938e68c4fd1c5be5d9f88c2bd40b8dae7ade36dcb90895c8c2955bd6a0693d501a7e9a50895f2aa3933a5296c54dc604cbb95a4ed5
@@ -4,7 +4,7 @@
4
4
 
5
5
  Simple integration of jquery-tablesorter into the asset pipeline.
6
6
 
7
- Current tablesorter version: 2.15.5 (2/23/2014), [documentation]
7
+ Current tablesorter version: 2.15.6 (3/7/2014), [documentation]
8
8
 
9
9
  Any issue associate with the js/css files, please report to [Mottie's fork].
10
10
 
@@ -25,6 +25,7 @@ Or install it yourself as:
25
25
  ## Requirements
26
26
 
27
27
  Rails 3.1 and higher (tested up to 4.1)
28
+
28
29
  Tested with ruby 1.9.3 - 2.1.0
29
30
 
30
31
  ## Usage
@@ -37,7 +38,7 @@ In your `application.js`
37
38
  //= require jquery-tablesorter
38
39
  ```
39
40
 
40
- This will require all jquery-tablesorter files (exclude addons, widgets, ...).
41
+ This will require all jquery-tablesorter files (excluding addons, widgets, ...).
41
42
 
42
43
  Or you can include single file with:
43
44
 
@@ -48,6 +49,7 @@ Or you can include single file with:
48
49
  //= require jquery-tablesorter/addons/pager/jquery.tablesorter.pager
49
50
  //= require jquery-tablesorter/widgets/widget-repeatheaders
50
51
  //= require jquery-tablesorter/parsers/parser-metric
52
+ //= require jquery-tablesorter/extras/jquery.quicksearch
51
53
  ```
52
54
 
53
55
  ### Stylesheet files
@@ -1,3 +1,3 @@
1
1
  module JqueryTablesorter
2
- VERSION = "1.10.3"
2
+ VERSION = "1.10.4"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * tablesorter pager plugin
3
- * updated 2/22/2014 (v2.15.4)
3
+ * updated 3/7/2014 (v2.15.6)
4
4
  */
5
5
  /*jshint browser:true, jquery:true, unused:false */
6
6
  ;(function($) {
@@ -124,7 +124,7 @@
124
124
  }
125
125
  },
126
126
 
127
- updatePageDisplay = function(table, p, flag) {
127
+ updatePageDisplay = function(table, p, completed) {
128
128
  var i, pg, s, out,
129
129
  c = table.config,
130
130
  f = c.$table.hasClass('hasFilters') && !p.ajaxUrl,
@@ -168,7 +168,7 @@
168
168
  }
169
169
  }
170
170
  pagerArrows(p);
171
- if (p.initialized && flag !== false) {
171
+ if (p.initialized && completed !== false) {
172
172
  c.$table.trigger('pagerComplete', p);
173
173
  // save pager info to storage
174
174
  if (p.savePages && ts.storage) {
@@ -263,6 +263,7 @@
263
263
  exception === 'abort' ? 'Ajax Request aborted' :
264
264
  'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
265
265
  c.$tbodies.eq(0).empty();
266
+ p.totalRows = 0;
266
267
  } else {
267
268
  // process ajax object
268
269
  if (!$.isArray(result)) {
@@ -273,7 +274,7 @@
273
274
  } else {
274
275
  // allow [ total, rows, headers ] or [ rows, total, headers ]
275
276
  t = isNaN(result[0]) && !isNaN(result[1]);
276
- //ensure a zero returned row count doesn't fail the logical ||
277
+ // ensure a zero returned row count doesn't fail the logical ||
277
278
  rr_count = result[t ? 1 : 0];
278
279
  p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
279
280
  d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
@@ -331,7 +332,8 @@
331
332
  }
332
333
  // make sure last pager settings are saved, prevents multiple server side calls with
333
334
  // the same parameters
334
- p.last.totalPages = p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
335
+ p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
336
+ p.last.totalRows = p.totalRows;
335
337
  p.last.currentFilters = p.currentFilters;
336
338
  p.last.sortList = (c.sortList || []).join(',');
337
339
  updatePageDisplay(table, p);
@@ -339,10 +341,12 @@
339
341
  $t.trigger('updateCache', [function(){
340
342
  if (p.initialized) {
341
343
  // apply widgets after table has rendered
342
- $t.trigger('applyWidgets');
343
- $t.trigger('pagerChange', p);
344
+ $t
345
+ .trigger('applyWidgets')
346
+ .trigger('pagerChange', p);
344
347
  }
345
348
  }]);
349
+
346
350
  }
347
351
  if (!p.initialized) {
348
352
  p.initialized = true;
@@ -429,6 +433,8 @@
429
433
 
430
434
  renderTable = function(table, rows, p) {
431
435
  var i, $tb,
436
+ $t = $(table),
437
+ c = table.config,
432
438
  l = rows && rows.length || 0, // rows may be undefined
433
439
  s = ( p.page * p.size ),
434
440
  e = ( s + p.size );
@@ -438,7 +444,7 @@
438
444
  moveToLastPage(table, p);
439
445
  }
440
446
  p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
441
- if (p.initialized) { $(table).trigger('pagerChange', p); }
447
+ if (p.initialized) { $t.trigger('pagerChange', p); }
442
448
 
443
449
  if ( !p.removeRows ) {
444
450
  hideRows(table, p);
@@ -447,7 +453,7 @@
447
453
  e = rows.length;
448
454
  }
449
455
  ts.clearTableBody(table);
450
- $tb = ts.processTbody(table, table.config.$tbodies.eq(0), true);
456
+ $tb = ts.processTbody(table, c.$tbodies.eq(0), true);
451
457
  for ( i = s; i < e; i++ ) {
452
458
  $tb.append(rows[i]);
453
459
  }
@@ -456,7 +462,10 @@
456
462
 
457
463
  updatePageDisplay(table, p);
458
464
  if ( !p.isDisabled ) { fixHeight(table, p); }
459
- $(table).trigger('applyWidgets');
465
+ $t.trigger('applyWidgets');
466
+ if (table.isUpdating) {
467
+ $t.trigger("updateComplete", table);
468
+ }
460
469
  },
461
470
 
462
471
  showAllRows = function(table, p){
@@ -484,15 +493,20 @@
484
493
  });
485
494
  },
486
495
 
487
- moveToPage = function(table, p, flag) {
496
+ moveToPage = function(table, p, pageMoved) {
488
497
  if ( p.isDisabled ) { return; }
489
498
  var c = table.config,
499
+ $t = $(table),
490
500
  l = p.last,
491
501
  pg = Math.min( p.totalPages, p.filteredPages );
492
502
  if ( p.page < 0 ) { p.page = 0; }
493
503
  if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
494
- // don't allow rendering multiple times on the same page/size/totalpages/filters/sorts
495
- if ( l.page === p.page && l.size === p.size && l.totalPages === p.totalPages &&
504
+ // fixes issue where one currentFilter is [] and the other is ['','',''],
505
+ // making the next if comparison think the filters are different (joined by commas). Fixes #202.
506
+ l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
507
+ p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
508
+ // don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
509
+ if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
496
510
  (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
497
511
  l.sortList === (c.sortList || []).join(',') ) { return; }
498
512
  if (c.debug) {
@@ -503,18 +517,22 @@
503
517
  size : p.size,
504
518
  // fixes #408; modify sortList otherwise it auto-updates
505
519
  sortList : (c.sortList || []).join(','),
506
- totalPages : p.totalPages,
520
+ totalRows : p.totalRows,
507
521
  currentFilters : p.currentFilters || []
508
522
  };
509
523
  if (p.ajax) {
510
524
  getAjax(table, p);
511
525
  } else if (!p.ajax) {
512
- renderTable(table, table.config.rowsCopy, p);
526
+ renderTable(table, c.rowsCopy, p);
513
527
  }
514
528
  $.data(table, 'pagerLastPage', p.page);
515
- if (p.initialized && flag !== false) {
516
- c.$table.trigger('pageMoved', p);
517
- c.$table.trigger('applyWidgets');
529
+ if (p.initialized && pageMoved !== false) {
530
+ $t
531
+ .trigger('pageMoved', p)
532
+ .trigger('applyWidgets');
533
+ if (table.isUpdating) {
534
+ $t.trigger('updateComplete');
535
+ }
518
536
  }
519
537
  },
520
538
 
@@ -1,5 +1,5 @@
1
1
  /**!
2
- * TableSorter 2.15.5 - Client-side table sorting with ease!
2
+ * TableSorter 2.15.6 - 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.15.5";
27
+ ts.version = "2.15.6";
28
28
 
29
29
  ts.parsers = [];
30
30
  ts.widgets = [];
@@ -331,7 +331,8 @@
331
331
  // empty table - fixes #206/#346
332
332
  if (isEmptyObject(c2)) {
333
333
  // run pager appender in case the table was just emptied
334
- return c.appender ? c.appender(table, rows) : '';
334
+ return c.appender ? c.appender(table, rows) :
335
+ table.isUpdating ? c.$table.trigger("updateComplete", table) : ''; // Fixes #532
335
336
  }
336
337
  if (c.debug) {
337
338
  appendTime = new Date();
@@ -368,9 +369,9 @@
368
369
  }
369
370
  // apply table widgets; but not before ajax completes
370
371
  if (!init && !c.appender) { ts.applyWidget(table); }
371
- // trigger sortend
372
- $(table).trigger("sortEnd", table);
373
- $(table).trigger("updateComplete", table);
372
+ if (table.isUpdating) {
373
+ c.$table.trigger("updateComplete", table);
374
+ }
374
375
  }
375
376
 
376
377
  // computeTableHeaderCellIndexes from:
@@ -582,92 +583,95 @@
582
583
  return (parsers && parsers[i]) ? parsers[i].type || '' : '';
583
584
  }
584
585
 
585
- function initSort(table, cell, e){
586
- var a, i, j, o, s,
586
+ function initSort(table, cell, event){
587
+ var arry, indx, col, order, s,
587
588
  c = table.config,
588
- k = !e[c.sortMultiSortKey],
589
- $table = $(table);
589
+ key = !event[c.sortMultiSortKey],
590
+ $table = c.$table;
590
591
  // Only call sortStart if sorting is enabled
591
592
  $table.trigger("sortStart", table);
592
593
  // get current column sort order
593
- cell.count = e[c.sortResetKey] ? 2 : (cell.count + 1) % (c.sortReset ? 3 : 2);
594
+ cell.count = event[c.sortResetKey] ? 2 : (cell.count + 1) % (c.sortReset ? 3 : 2);
594
595
  // reset all sorts on non-current column - issue #30
595
596
  if (c.sortRestart) {
596
- i = cell;
597
+ indx = cell;
597
598
  c.$headers.each(function() {
598
599
  // only reset counts on columns that weren't just clicked on and if not included in a multisort
599
- if (this !== i && (k || !$(this).is('.' + ts.css.sortDesc + ',.' + ts.css.sortAsc))) {
600
+ if (this !== indx && (key || !$(this).is('.' + ts.css.sortDesc + ',.' + ts.css.sortAsc))) {
600
601
  this.count = -1;
601
602
  }
602
603
  });
603
604
  }
604
605
  // get current column index
605
- i = cell.column;
606
+ indx = cell.column;
606
607
  // user only wants to sort on one column
607
- if (k) {
608
+ if (key) {
608
609
  // flush the sort list
609
610
  c.sortList = [];
610
611
  if (c.sortForce !== null) {
611
- a = c.sortForce;
612
- for (j = 0; j < a.length; j++) {
613
- if (a[j][0] !== i) {
614
- c.sortList.push(a[j]);
612
+ arry = c.sortForce;
613
+ for (col = 0; col < arry.length; col++) {
614
+ if (arry[col][0] !== indx) {
615
+ c.sortList.push(arry[col]);
615
616
  }
616
617
  }
617
618
  }
618
619
  // add column to sort list
619
- o = cell.order[cell.count];
620
- if (o < 2) {
621
- c.sortList.push([i, o]);
620
+ order = cell.order[cell.count];
621
+ if (order < 2) {
622
+ c.sortList.push([indx, order]);
622
623
  // add other columns if header spans across multiple
623
624
  if (cell.colSpan > 1) {
624
- for (j = 1; j < cell.colSpan; j++) {
625
- c.sortList.push([i + j, o]);
625
+ for (col = 1; col < cell.colSpan; col++) {
626
+ c.sortList.push([indx + col, order]);
626
627
  }
627
628
  }
628
629
  }
629
630
  // multi column sorting
630
631
  } else {
631
- // get rid of the sortAppend before adding more - fixes issue #115
632
+ // get rid of the sortAppend before adding more - fixes issue #115 & #523
632
633
  if (c.sortAppend && c.sortList.length > 1) {
633
- if (ts.isValueInArray(c.sortAppend[0][0], c.sortList)) {
634
- c.sortList.pop();
634
+ for (col = 0; col < c.sortAppend.length; col++) {
635
+ s = ts.isValueInArray(c.sortAppend[col][0], c.sortList);
636
+ if (s >= 0) {
637
+ c.sortList.splice(s,1);
638
+ }
635
639
  }
636
640
  }
637
641
  // the user has clicked on an already sorted column
638
- if (ts.isValueInArray(i, c.sortList)) {
642
+ if (ts.isValueInArray(indx, c.sortList) >= 0) {
639
643
  // reverse the sorting direction
640
- for (j = 0; j < c.sortList.length; j++) {
641
- s = c.sortList[j];
642
- o = c.$headers[s[0]];
643
- if (s[0] === i) {
644
- // o.count seems to be incorrect when compared to cell.count
645
- s[1] = o.order[cell.count];
644
+ for (col = 0; col < c.sortList.length; col++) {
645
+ s = c.sortList[col];
646
+ order = c.$headers[s[0]];
647
+ if (s[0] === indx) {
648
+ // order.count seems to be incorrect when compared to cell.count
649
+ s[1] = order.order[cell.count];
646
650
  if (s[1] === 2) {
647
- c.sortList.splice(j,1);
648
- o.count = -1;
651
+ c.sortList.splice(col,1);
652
+ order.count = -1;
649
653
  }
650
654
  }
651
655
  }
652
656
  } else {
653
657
  // add column to sort list array
654
- o = cell.order[cell.count];
655
- if (o < 2) {
656
- c.sortList.push([i, o]);
658
+ order = cell.order[cell.count];
659
+ if (order < 2) {
660
+ c.sortList.push([indx, order]);
657
661
  // add other columns if header spans across multiple
658
662
  if (cell.colSpan > 1) {
659
- for (j = 1; j < cell.colSpan; j++) {
660
- c.sortList.push([i + j, o]);
663
+ for (col = 1; col < cell.colSpan; col++) {
664
+ c.sortList.push([indx + col, order]);
661
665
  }
662
666
  }
663
667
  }
664
668
  }
665
669
  }
666
670
  if (c.sortAppend !== null) {
667
- a = c.sortAppend;
668
- for (j = 0; j < a.length; j++) {
669
- if (a[j][0] !== i) {
670
- c.sortList.push(a[j]);
671
+ arry = c.sortAppend;
672
+ for (col = 0; col < arry.length; col++) {
673
+ if (arry[col][0] !== indx) {
674
+ c.sortList.push(arry[col]);
671
675
  }
672
676
  }
673
677
  }
@@ -679,6 +683,7 @@
679
683
  setHeadersCss(table);
680
684
  multisort(table);
681
685
  appendToTable(table);
686
+ $table.trigger("sortEnd", table);
682
687
  }, 1);
683
688
  }
684
689
 
@@ -751,8 +756,8 @@
751
756
  }
752
757
 
753
758
  function resortComplete($table, callback){
754
- var c = $table[0].config;
755
- if (c.pager && !c.pager.ajax) {
759
+ var table = $table[0];
760
+ if (table.isUpdating) {
756
761
  $table.trigger('updateComplete');
757
762
  }
758
763
  if (typeof callback === "function") {
@@ -761,12 +766,13 @@
761
766
  }
762
767
 
763
768
  function checkResort($table, flag, callback) {
769
+ var sl = $table[0].config.sortList;
764
770
  // don't try to resort if the table is still processing
765
771
  // this will catch spamming of the updateCell method
766
- if (flag !== false && !$table[0].isProcessing) {
767
- $table.trigger("sorton", [$table[0].config.sortList, function(){
772
+ if (flag !== false && !$table[0].isProcessing && sl.length) {
773
+ $table.trigger("sorton", [sl, function(){
768
774
  resortComplete($table, callback);
769
- }]);
775
+ }, true]);
770
776
  } else {
771
777
  resortComplete($table, callback);
772
778
  }
@@ -777,7 +783,7 @@
777
783
  $table = c.$table;
778
784
  // apply easy methods that trigger bound events
779
785
  $table
780
- .unbind('sortReset update updateRows updateCell updateAll addRows sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join('.tablesorter '))
786
+ .unbind('sortReset update updateRows updateCell updateAll addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave '.split(' ').join('.tablesorter '))
781
787
  .bind("sortReset.tablesorter", function(e){
782
788
  e.stopPropagation();
783
789
  c.sortList = [];
@@ -787,6 +793,7 @@
787
793
  })
788
794
  .bind("updateAll.tablesorter", function(e, resort, callback){
789
795
  e.stopPropagation();
796
+ table.isUpdating = true;
790
797
  ts.refreshWidgets(table, true, true);
791
798
  ts.restoreHeaders(table);
792
799
  buildHeaders(table);
@@ -796,12 +803,14 @@
796
803
  })
797
804
  .bind("update.tablesorter updateRows.tablesorter", function(e, resort, callback) {
798
805
  e.stopPropagation();
806
+ table.isUpdating = true;
799
807
  // update sorting (if enabled/disabled)
800
808
  updateHeader(table);
801
809
  commonUpdate(table, resort, callback);
802
810
  })
803
811
  .bind("updateCell.tablesorter", function(e, cell, resort, callback) {
804
812
  e.stopPropagation();
813
+ table.isUpdating = true;
805
814
  $table.find(c.selectorRemove).remove();
806
815
  // get position from the dom
807
816
  var l, row, icell,
@@ -823,6 +832,7 @@
823
832
  })
824
833
  .bind("addRows.tablesorter", function(e, $row, resort, callback) {
825
834
  e.stopPropagation();
835
+ table.isUpdating = true;
826
836
  if (isEmptyObject(c.cache)) {
827
837
  // empty table, do an update instead - fixes #450
828
838
  updateHeader(table);
@@ -853,6 +863,9 @@
853
863
  checkResort($table, resort, callback);
854
864
  }
855
865
  })
866
+ .bind("updateComplete.tablesorter", function(){
867
+ table.isUpdating = false;
868
+ })
856
869
  .bind("sorton.tablesorter", function(e, list, callback, init) {
857
870
  var c = table.config;
858
871
  e.stopPropagation();
@@ -867,6 +880,7 @@
867
880
  // sort the table and append it to the dom
868
881
  multisort(table);
869
882
  appendToTable(table, init);
883
+ $table.trigger("sortEnd", this);
870
884
  if (typeof callback === "function") {
871
885
  callback(table);
872
886
  }
@@ -991,7 +1005,7 @@
991
1005
  ts.applyWidget(table, true);
992
1006
  // if user has supplied a sort list to constructor
993
1007
  if (c.sortList.length > 0) {
994
- $table.trigger("sorton", [c.sortList, {}, !c.initWidgets]);
1008
+ $table.trigger("sorton", [c.sortList, {}, !c.initWidgets, true]);
995
1009
  } else {
996
1010
  setHeadersCss(table);
997
1011
  if (c.initWidgets) {
@@ -1032,7 +1046,7 @@
1032
1046
  // get headers from the sortList
1033
1047
  $h = $h.filter(function(){
1034
1048
  // get data-column from attr to keep compatibility with jQuery 1.2.6
1035
- return this.sortDisabled ? false : ts.isValueInArray( parseFloat($(this).attr('data-column')), c.sortList);
1049
+ return this.sortDisabled ? false : ts.isValueInArray( parseFloat($(this).attr('data-column')), c.sortList) >= 0;
1036
1050
  });
1037
1051
  }
1038
1052
  $h.addClass(ts.css.processing + ' ' + c.cssProcessing);
@@ -1132,7 +1146,7 @@
1132
1146
  // disable tablesorter
1133
1147
  $t
1134
1148
  .removeData('tablesorter')
1135
- .unbind('sortReset update updateAll updateRows updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd '.split(' ').join('.tablesorter '));
1149
+ .unbind('sortReset update updateAll updateRows updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd '.split(' ').join('.tablesorter '));
1136
1150
  c.$headers.add($f)
1137
1151
  .removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone].join(' ') )
1138
1152
  .removeAttr('data-column');
@@ -1152,6 +1166,8 @@
1152
1166
  // regex used in natural sort
1153
1167
  ts.regex = {
1154
1168
  chunk : /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi, // chunk/tokenize numbers & letters
1169
+ schunk: /^\\0/, // start chunk
1170
+ echunk: /\\0$/, // end chunk
1155
1171
  hex: /^0x[0-9a-f]+$/i // hex
1156
1172
  };
1157
1173
 
@@ -1168,8 +1184,8 @@
1168
1184
  if ( xD > yD ) { return 1; }
1169
1185
  }
1170
1186
  // chunk/tokenize
1171
- xN = a.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
1172
- yN = b.replace(r.chunk, '\\0$1\\0').replace(/\\0$/, '').replace(/^\\0/, '').split('\\0');
1187
+ xN = a.replace(r.chunk, '\\0$1\\0').replace(r.echunk, '').replace(r.schunk, '').split('\\0');
1188
+ yN = b.replace(r.chunk, '\\0$1\\0').replace(r.echunk, '').replace(r.schunk, '').split('\\0');
1173
1189
  mx = Math.max(xN.length, yN.length);
1174
1190
  // natural sorting through split numeric strings and default strings
1175
1191
  for (i = 0; i < mx; i++) {
@@ -1291,14 +1307,14 @@
1291
1307
  };
1292
1308
 
1293
1309
  // *** utilities ***
1294
- ts.isValueInArray = function(v, a) {
1295
- var i, l = a.length;
1296
- for (i = 0; i < l; i++) {
1297
- if (a[i][0] === v) {
1298
- return true;
1310
+ ts.isValueInArray = function(column, arry) {
1311
+ var indx, len = arry.length;
1312
+ for (indx = 0; indx < len; indx++) {
1313
+ if (arry[indx][0] === column) {
1314
+ return indx;
1299
1315
  }
1300
1316
  }
1301
- return false;
1317
+ return -1;
1302
1318
  };
1303
1319
 
1304
1320
  ts.addParser = function(parser) {
@@ -1544,7 +1560,7 @@
1544
1560
  return (/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/).test(s);
1545
1561
  },
1546
1562
  format: function(s, table) {
1547
- return s ? ts.formatFloat((s !== "") ? (new Date(s.replace(/-/g, "/")).getTime() || "") : "", table) : s;
1563
+ return s ? ts.formatFloat((s !== "") ? (new Date(s.replace(/-/g, "/")).getTime() || s) : "", table) : s;
1548
1564
  },
1549
1565
  type: "numeric"
1550
1566
  });
@@ -1568,7 +1584,7 @@
1568
1584
  return (/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i).test(s) || (/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i).test(s);
1569
1585
  },
1570
1586
  format: function(s, table) {
1571
- return s ? ts.formatFloat( (new Date(s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || ''), table) : s;
1587
+ return s ? ts.formatFloat( (new Date(s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || s), table) : s;
1572
1588
  },
1573
1589
  type: "numeric"
1574
1590
  });
@@ -1593,7 +1609,7 @@
1593
1609
  s = s.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$1/$2/$3");
1594
1610
  }
1595
1611
  }
1596
- return s ? ts.formatFloat( (new Date(s).getTime() || ''), table) : s;
1612
+ return s ? ts.formatFloat( (new Date(s).getTime() || s), table) : s;
1597
1613
  },
1598
1614
  type: "numeric"
1599
1615
  });
@@ -1604,7 +1620,7 @@
1604
1620
  return (/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i).test(s);
1605
1621
  },
1606
1622
  format: function(s, table) {
1607
- return s ? ts.formatFloat( (new Date("2000/01/01 " + s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || ""), table) : s;
1623
+ return s ? ts.formatFloat( (new Date("2000/01/01 " + s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || s), table) : s;
1608
1624
  },
1609
1625
  type: "numeric"
1610
1626
  });
@@ -487,7 +487,7 @@ tsff = ts.filterFormatter = {
487
487
  endOfDay : true,
488
488
  // include ANY jQuery UI spinner options below
489
489
 
490
- defaultDate : '', // ******************************** FIX THIS *******************************************
490
+ defaultDate : '',
491
491
 
492
492
  changeMonth : true,
493
493
  changeYear : true,
@@ -1,4 +1,4 @@
1
- /*! tableSorter 2.8+ widgets - updated 2/21/2014 (v2.15.3)
1
+ /*! tableSorter 2.8+ widgets - updated 3/7/2014 (v2.15.6)
2
2
  *
3
3
  * Column Styles
4
4
  * Column Filters
@@ -654,15 +654,21 @@ ts.filter = {
654
654
  c.$table.trigger('filterInit');
655
655
  },
656
656
  setDefaults: function(table, c, wo) {
657
- var isArray, saved,
657
+ var isArray, saved, indx,
658
658
  // get current (default) filters
659
- filters = ts.getFilters(table);
659
+ filters = ts.getFilters(table) || [];
660
660
  if (wo.filter_saveFilters && ts.storage) {
661
661
  saved = ts.storage( table, 'tablesorter-filters' ) || [];
662
662
  isArray = $.isArray(saved);
663
663
  // make sure we're not just getting an empty array
664
664
  if ( !(isArray && saved.join('') === '' || !isArray) ) { filters = saved; }
665
665
  }
666
+ // if no filters saved, then check default settings
667
+ if (filters.join('') === '') {
668
+ for (indx = 0; indx < c.columns; indx++) {
669
+ filters[indx] = c.$headers.filter('[data-column="' + indx + '"]:last').attr(wo.filter_defaultAttrib) || filters[indx];
670
+ }
671
+ }
666
672
  c.$table.data('lastSearch', filters);
667
673
  return filters;
668
674
  },
@@ -1010,6 +1016,7 @@ ts.filter = {
1010
1016
  c.$table.trigger('filterEnd');
1011
1017
  },
1012
1018
  buildSelect: function(table, column, updating, onlyavail) {
1019
+ if (!table.config.cache || $.isEmptyObject(table.config.cache)) { return; }
1013
1020
  column = parseInt(column, 10);
1014
1021
  var indx, rowIndex, tbodyIndex, len, currentValue, txt, $filters,
1015
1022
  c = table.config,
@@ -26,7 +26,7 @@
26
26
  if (result[12]) { date.setMilliseconds(Number('0.' + result[12]) * 1000); }
27
27
  return date;
28
28
  }
29
- return 0;
29
+ return s;
30
30
  },
31
31
  type : 'numeric'
32
32
  });
@@ -18,10 +18,10 @@
18
18
  return false;
19
19
  },
20
20
  format: function(s, table) {
21
- var j = -1, c = table.config;
22
- s = c.ignoreCase ? s.toLocaleLowerCase() : s;
21
+ var j = -1, c = table.config,
22
+ n = c.ignoreCase ? s.toLocaleLowerCase() : s;
23
23
  $.each(ts.dates[ 'month' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
24
- if (j < 0 && s.match(v)) { j = i; }
24
+ if (j < 0 && n.match(v)) { j = i; }
25
25
  });
26
26
  // return s (original string) if there isn't a match
27
27
  // (non-weekdays will sort separately and empty cells will sort as expected)
@@ -18,12 +18,12 @@
18
18
  });
19
19
 
20
20
  ts.formatDate = function(s, regex, format, table){
21
- s = s
22
- // replace separators
23
- .replace(/\s+/g," ").replace(/[-.,]/g, "/")
24
- // reformat xx/xx/xx to mm/dd/19yy;
25
- .replace(regex, format);
26
- var d = new Date(s),
21
+ var n = s
22
+ // replace separators
23
+ .replace(/\s+/g," ").replace(/[-.,]/g, "/")
24
+ // reformat xx/xx/xx to mm/dd/19yy;
25
+ .replace(regex, format),
26
+ d = new Date(n),
27
27
  y = d.getFullYear(),
28
28
  rng = table && table.config.dateRange || range,
29
29
  now = new Date().getFullYear();
@@ -32,7 +32,7 @@
32
32
  while (now - y > rng) {
33
33
  y += 100;
34
34
  }
35
- return d.setFullYear(y);
35
+ return d.setFullYear(y) || s;
36
36
  };
37
37
 
38
38
  $.tablesorter.addParser({
@@ -36,14 +36,15 @@
36
36
  return false;
37
37
  },
38
38
  format: function(s, table, cell, cellIndex) {
39
- var $c = $(cell).find('input'),
40
- isChecked = $c[0].checked;
39
+ var $c = $(cell),
40
+ $input = $c.find('input[type="checkbox"]'),
41
+ isChecked = $input.length ? $input[0].checked : '';
41
42
  // adding class to row, indicating that a checkbox is checked; includes
42
43
  // a column index in case more than one checkbox happens to be in a row
43
44
  $c.closest('tr').toggleClass('checked-' + cellIndex, isChecked);
44
45
  // returning plain language here because this is what is shown in the
45
46
  // group headers - change it as desired
46
- return $c.length ? isChecked ? 'checked' : 'unchecked' : s;
47
+ return $input.length ? isChecked ? 'checked' : 'unchecked' : s;
47
48
  },
48
49
  parsed : true, // filter widget flag
49
50
  type: "text"
@@ -62,18 +62,21 @@ tsColSel = ts.columnSelector = {
62
62
  var $this = $(this),
63
63
  // if no data-priority is assigned, default to 1, but don't remove it from the selector list
64
64
  priority = $this.attr(wo.columnSelector_priority) || 1,
65
- colId = $this.attr('data-column');
65
+ colId = $this.attr('data-column'),
66
+ state = ts.getData(this, c.headers[colId], 'columnSelector');
67
+
66
68
 
67
69
  // if this column not hidable at all
68
70
  // include getData check (includes "columnSelector-false" class, data attribute, etc)
69
- if ( isNaN(priority) && priority.length > 0 || ts.getData(this, c.headers[colId], 'columnSelector') == 'false' ||
71
+ if ( isNaN(priority) && priority.length > 0 || state === 'disable' ||
70
72
  ( wo.columnSelector_columns[colId] && wo.columnSelector_columns[colId] === 'disable') ) {
71
73
  return true; // goto next
72
74
  }
73
75
 
74
- // set default state
76
+ // set default state; storage takes priority
75
77
  colSel.states[colId] = saved && typeof(saved[colId]) !== 'undefined' ?
76
- saved[colId] : typeof(wo.columnSelector_columns[colId]) !== 'undefined' ? wo.columnSelector_columns[colId] : true;
78
+ saved[colId] : typeof(wo.columnSelector_columns[colId]) !== 'undefined' ?
79
+ wo.columnSelector_columns[colId] : state === 'true' || !(state === 'false');
77
80
  colSel.$column[colId] = $(this);
78
81
 
79
82
  // set default col title
@@ -135,8 +138,8 @@ tsColSel = ts.columnSelector = {
135
138
  c.selector.$popup.find('.tablesorter-column-selector')
136
139
  .html( colSel.$container.html() )
137
140
  .find('input').each(function(){
138
- var indx = $(this).attr('data-column')
139
- $(this).prop( 'checked', indx === 'auto' ? wo.columnSelector_mediaqueryState : colSel.states[indx] )
141
+ var indx = $(this).attr('data-column');
142
+ $(this).prop( 'checked', indx === 'auto' ? wo.columnSelector_mediaqueryState : colSel.states[indx] );
140
143
  });
141
144
  }
142
145
  }).change();
@@ -210,8 +213,8 @@ tsColSel = ts.columnSelector = {
210
213
  },
211
214
 
212
215
  attachTo : function(table, elm) {
216
+ table = $(table)[0];
213
217
  var colSel, wo, indx,
214
- table = $(table)[0],
215
218
  c = table.config,
216
219
  $popup = $(elm);
217
220
  if ($popup.length && c) {
@@ -225,7 +228,7 @@ tsColSel = ts.columnSelector = {
225
228
  .html( colSel.$container.html() )
226
229
  .find('input').each(function(){
227
230
  var indx = $(this).attr('data-column');
228
- $(this).prop( 'checked', indx === 'auto' ? wo.columnSelector_mediaqueryState : colSel.states[indx] )
231
+ $(this).prop( 'checked', indx === 'auto' ? wo.columnSelector_mediaqueryState : colSel.states[indx] );
229
232
  });
230
233
  colSel.$popup = $popup.on('change', 'input', function(){
231
234
  // data input
@@ -1,4 +1,4 @@
1
- /*! tablesorter Grouping widget - updated 12/18/2013 (core v2.15.0)
1
+ /*! tablesorter Grouping widget - updated 3/7/2014 (core v2.15.6)
2
2
  * Requires tablesorter v2.8+ and jQuery 1.7+
3
3
  * by Rob Garrison
4
4
  */
@@ -53,9 +53,10 @@ ts.grouping = {
53
53
 
54
54
  update : function(table, c, wo){
55
55
  if ($.isEmptyObject(c.cache)) { return; }
56
- var rowIndex, tbodyIndex, currentGroup, $rows, groupClass, grouping, time, cache,
56
+ var rowIndex, tbodyIndex, currentGroup, $rows, groupClass, grouping, time, cache, saveName, direction,
57
57
  lang = wo.grouping_language,
58
58
  group = '',
59
+ savedGroup = false,
59
60
  column = c.sortList[0] ? c.sortList[0][0] : -1;
60
61
  c.$table
61
62
  .find('tr.group-hidden').removeClass('group-hidden').end()
@@ -66,19 +67,33 @@ ts.grouping = {
66
67
  }
67
68
  if (column >= 0 && !c.$headers.filter('[data-column="' + column + '"]:last').hasClass('group-false')) {
68
69
  if (c.debug){ time = new Date(); }
70
+ wo.group_currentGroup = ''; // save current groups
71
+ wo.group_currentGroups = {};
72
+
73
+ // group class finds "group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}"
74
+ groupClass = (c.$headers.filter('[data-column="' + column + '"]:last').attr('class') || '').match(/(group-\w+(-\w+)?)/g);
75
+ // grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
76
+ grouping = groupClass ? groupClass[0].split('-') : ['group','letter',1]; // default to letter 1
77
+
78
+ // save current grouping
79
+ if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
80
+ wo.group_currentGroups = ts.storage( table, 'tablesorter-groups' ) || {};
81
+ // include direction when grouping numbers > 1 (reversed direction shows different range values)
82
+ direction = (grouping[1] === 'number' && grouping[2] > 1) ? 'dir' + c.sortList[0][1] : '';
83
+ // combine column, sort direction & grouping as save key
84
+ saveName = wo.group_currentGroup = '' + column + direction + grouping.join('');
85
+ if (!wo.group_currentGroups[saveName]) {
86
+ wo.group_currentGroups[saveName] = [];
87
+ } else {
88
+ savedGroup = true;
89
+ }
90
+ }
69
91
  for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++) {
70
92
  cache = c.cache[tbodyIndex].normalized;
71
93
  group = ''; // clear grouping across tbodies
72
94
  $rows = c.$tbodies.eq(tbodyIndex).children('tr').not('.' + c.cssChildRow);
73
- if (wo.group_collapsed && wo.group_collapsible) {
74
- $rows.addClass('group-hidden');
75
- }
76
95
  for (rowIndex = 0; rowIndex < $rows.length; rowIndex++) {
77
96
  if ( $rows.eq(rowIndex).is(':visible') ) {
78
- // group class finds "group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}"
79
- groupClass = (c.$headers.filter('[data-column="' + column + '"]:last').attr('class') || '').match(/(group-\w+(-\w+)?)/g);
80
- // grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
81
- grouping = groupClass ? groupClass[0].split('-') : ['','letter',1]; // default to letter 1
82
97
  // fixes #438
83
98
  if (ts.grouping.types[grouping[1]]) {
84
99
  currentGroup = cache[rowIndex] ?
@@ -95,22 +110,29 @@ ts.grouping = {
95
110
  currentGroup = wo.group_formatter((currentGroup || '').toString(), column, table, c, wo) || currentGroup;
96
111
  }
97
112
  $rows.eq(rowIndex).before('<tr class="group-header ' + c.selectorRemove.slice(1) +
98
- (wo.group_collapsed && wo.group_collapsible ? ' collapsed' : '') + '" unselectable="on"><td colspan="' +
113
+ // (wo.group_collapsed && wo.group_collapsible ? ' collapsed' : '') +
114
+ '" unselectable="on"><td colspan="' +
99
115
  c.columns + '">' + (wo.group_collapsible ? '<i/>' : '') + '<span class="group-name">' +
100
116
  currentGroup + '</span><span class="group-count"></span></td></tr>');
117
+ if (wo.group_saveGroups && !savedGroup && wo.group_collapsed && wo.group_collapsible) {
118
+ // all groups start collapsed
119
+ wo.group_currentGroups[wo.group_currentGroup].push(currentGroup);
120
+ }
101
121
  }
102
122
  }
103
123
  }
104
124
  }
105
125
  }
106
- $rows = c.$table.find('tr.group-header').bind('selectstart', false);
107
- if (wo.group_count || $.isFunction(wo.group_callback)) {
108
- $rows.each(function(){
109
- var $rows,
110
- $row = $(this),
111
- $label = $row.find('.group-count');
126
+ c.$table.find('tr.group-header')
127
+ .bind('selectstart', false)
128
+ .each(function(){
129
+ var isHidden, $label,
130
+ $row = $(this),
131
+ name = $row.find('.group-name').text().toLowerCase(),
132
+ $rows = $row.nextUntil('tr.group-header').filter(':visible');
133
+ if (wo.group_count || $.isFunction(wo.group_callback)) {
134
+ $label = $row.find('.group-count');
112
135
  if ($label.length) {
113
- $rows = $row.nextUntil('tr.group-header').filter(':visible');
114
136
  if (wo.group_count) {
115
137
  $label.html( wo.group_count.replace(/\{num\}/g, $rows.length) );
116
138
  }
@@ -118,13 +140,71 @@ ts.grouping = {
118
140
  wo.group_callback($row.find('td'), $rows, column, table);
119
141
  }
120
142
  }
121
- });
122
- }
143
+ }
144
+ if (wo.group_saveGroups && wo.group_currentGroups[wo.group_currentGroup].length) {
145
+ isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1;
146
+ $row.toggleClass('collapsed', isHidden);
147
+ $rows.toggleClass('group-hidden', isHidden);
148
+ } else if (wo.group_collapsed && wo.group_collapsible) {
149
+ $row.addClass('collapsed');
150
+ $rows.addClass('group-hidden');
151
+ }
152
+ });
123
153
  c.$table.trigger(wo.group_complete);
124
154
  if (c.debug) {
125
155
  $.tablesorter.benchmark("Applying groups widget: ", time);
126
156
  }
127
157
  }
158
+ },
159
+
160
+ bindEvents : function(table, c, wo){
161
+ if (wo.group_collapsible) {
162
+ wo.group_currentGroups = [];
163
+ // .on() requires jQuery 1.7+
164
+ c.$table.on('click toggleGroup', 'tr.group-header', function(event){
165
+ event.stopPropagation();
166
+ var isCollapsed, $groups, indx,
167
+ $this = $(this),
168
+ name = $this.find('.group-name').text();
169
+ // use shift-click to toggle ALL groups
170
+ if (event.type === 'click' && event.shiftKey) {
171
+ $this.siblings('.group-header').trigger('toggleGroup');
172
+ }
173
+ $this.toggleClass('collapsed');
174
+ // nextUntil requires jQuery 1.4+
175
+ $this.nextUntil('tr.group-header').toggleClass('group-hidden', $this.hasClass('collapsed') );
176
+ // save collapsed groups
177
+ if (wo.group_saveGroups && ts.storage) {
178
+ $groups = c.$table.find('.group-header');
179
+ isCollapsed = $this.hasClass('collapsed');
180
+ if (!wo.group_currentGroups[wo.group_currentGroup]) {
181
+ wo.group_currentGroups[wo.group_currentGroup] = [];
182
+ }
183
+ if (isCollapsed && wo.group_currentGroup) {
184
+ wo.group_currentGroups[wo.group_currentGroup].push( name );
185
+ } else if (wo.group_currentGroup) {
186
+ indx = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] );
187
+ if (indx > -1) {
188
+ wo.group_currentGroups[wo.group_currentGroup].splice( indx, 1 );
189
+ }
190
+ }
191
+ ts.storage( table, 'tablesorter-groups', wo.group_currentGroups );
192
+ }
193
+ });
194
+ }
195
+ $(wo.group_saveReset).on('click', function(){
196
+ ts.grouping.clearSavedGroups(table);
197
+ });
198
+ c.$table.on('pagerChange.tsgrouping', function(){
199
+ ts.grouping.update(table, c, wo);
200
+ });
201
+ },
202
+
203
+ clearSavedGroups: function(table){
204
+ if (table && ts.storage) {
205
+ ts.storage(table, 'tablesorter-groups', '');
206
+ ts.grouping.update(table, table.config, table.config.widgetOptions);
207
+ }
128
208
  }
129
209
 
130
210
  };
@@ -135,6 +215,8 @@ ts.addWidget({
135
215
  options: {
136
216
  group_collapsible : true, // make the group header clickable and collapse the rows below it.
137
217
  group_collapsed : false, // start with all groups collapsed
218
+ group_saveGroups : true, // remember collapsed groups
219
+ group_saveReset : null, // element to clear saved collapsed groups
138
220
  group_count : ' ({num})', // if not false, the "{num}" string is replaced with the number of rows in the group
139
221
  group_separator : '-', // group name separator; used when group-separator-# class is used.
140
222
  group_formatter : null, // function(txt, column, table, c, wo) { return txt; }
@@ -151,23 +233,7 @@ ts.addWidget({
151
233
  group_dateString : function(date) { return date.toLocaleString(); }
152
234
  },
153
235
  init: function(table, thisWidget, c, wo){
154
- if (wo.group_collapsible) {
155
- // .on() requires jQuery 1.7+
156
- c.$table.on('click toggleGroup', 'tr.group-header', function(event){
157
- event.stopPropagation();
158
- var $this = $(this);
159
- // use shift-click to toggle ALL groups
160
- if (event.type === 'click' && event.shiftKey) {
161
- $this.siblings('.group-header').trigger('toggleGroup');
162
- }
163
- $this.toggleClass('collapsed');
164
- // nextUntil requires jQuery 1.4+
165
- $this.nextUntil('tr.group-header').toggleClass('group-hidden', $this.hasClass('collapsed') );
166
- });
167
- }
168
- c.$table.on('pagerChange', function(){
169
- ts.grouping.update(table, c, wo);
170
- });
236
+ ts.grouping.bindEvents(table, c, wo);
171
237
  },
172
238
  format: function(table, c, wo) {
173
239
  ts.grouping.update(table, c, wo);
@@ -175,6 +241,7 @@ ts.addWidget({
175
241
  remove : function(table, c, wo){
176
242
  c.$table
177
243
  .off('click', 'tr.group-header')
244
+ .off('pagerChange.tsgrouping')
178
245
  .find('.group-hidden').removeClass('group-hidden').end()
179
246
  .find('tr.group-header').remove();
180
247
  }
@@ -0,0 +1,32 @@
1
+ /*! tablesorter headerTitles widget - updated 3/5/2014 (core v2.15.6)
2
+ * Requires tablesorter v2.8+ and jQuery 1.7+
3
+ * by Rob Garrison
4
+ */
5
+ /*jshint browser:true, jquery:true, unused:false */
6
+ /*global jQuery: false */
7
+ ;(function($){
8
+ "use strict";
9
+
10
+ $.tablesorter.addWidget({
11
+ id: 'headerTitles',
12
+ options: {
13
+ headerTitle_prefix : 'Sort: ',
14
+ headerTitle_text : [ 'A - Z', 'Z - A' ],
15
+ headerTitle_numeric : [ '0 - 9', '9 - 0' ]
16
+ },
17
+ format: function (table, c, wo) {
18
+ var txt;
19
+ // clear out all titles
20
+ c.$headers.attr('title', '');
21
+ // only add titles to sorted columns
22
+ $.each(c.sortList, function(indx, group) {
23
+ txt = wo.headerTitle_prefix + wo['headerTitle_' + (c.parsers[ group[0] ].type || 'text')][ group[1] ];
24
+ c.$headers.filter('[data-column="' + group[0] + '"]').attr('title', txt);
25
+ });
26
+ },
27
+ remove: function (table, c) {
28
+ c.$headers.attr('title', '');
29
+ }
30
+ });
31
+
32
+ })(jQuery);
@@ -1,4 +1,4 @@
1
- /* Pager widget (beta) for TableSorter 2/23/2014 (v2.15.5) */
1
+ /* Pager widget (beta) for TableSorter 3/7/2014 (v2.15.6) */
2
2
  /*jshint browser:true, jquery:true, unused:false */
3
3
  ;(function($){
4
4
  "use strict";
@@ -150,7 +150,6 @@ tsp = ts.pager = {
150
150
  // page size selector
151
151
  p.$size = p.$container.find(s.pageSize);
152
152
  p.totalRows = c.$tbodies.eq(0).children().length;
153
-
154
153
  p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
155
154
  c.appender = tsp.appender;
156
155
  if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
@@ -315,7 +314,7 @@ tsp = ts.pager = {
315
314
  }
316
315
  },
317
316
 
318
- updatePageDisplay: function(table, c, flag) {
317
+ updatePageDisplay: function(table, c, completed) {
319
318
  var i, pg, s, out,
320
319
  wo = c.widgetOptions,
321
320
  p = c.pager,
@@ -361,7 +360,7 @@ tsp = ts.pager = {
361
360
  }
362
361
  }
363
362
  tsp.pagerArrows(c);
364
- if (p.initialized && flag !== false) {
363
+ if (p.initialized && completed !== false) {
365
364
  c.$table.trigger('pagerComplete', c);
366
365
  // save pager info to storage
367
366
  if (wo.pager_savePages && ts.storage) {
@@ -453,6 +452,7 @@ tsp = ts.pager = {
453
452
  }
454
453
  ts.showError(table, exception.message + ' (' + xhr.status + ')');
455
454
  c.$tbodies.eq(0).empty();
455
+ p.totalRows = 0;
456
456
  } else {
457
457
  // process ajax object
458
458
  if (!$.isArray(result)) {
@@ -463,7 +463,7 @@ tsp = ts.pager = {
463
463
  } else {
464
464
  // allow [ total, rows, headers ] or [ rows, total, headers ]
465
465
  t = isNaN(result[0]) && !isNaN(result[1]);
466
- //ensure a zero returned row count doesn't fail the logical ||
466
+ // ensure a zero returned row count doesn't fail the logical ||
467
467
  rr_count = result[t ? 1 : 0];
468
468
  p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
469
469
  d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
@@ -521,7 +521,8 @@ tsp = ts.pager = {
521
521
  }
522
522
  // make sure last pager settings are saved, prevents multiple server side calls with
523
523
  // the same parameters
524
- p.last.totalPages = p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
524
+ p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
525
+ p.last.totalRows = p.totalRows;
525
526
  p.last.currentFilters = p.currentFilters;
526
527
  p.last.sortList = (c.sortList || []).join(',');
527
528
  tsp.updatePageDisplay(table, c);
@@ -650,6 +651,9 @@ tsp = ts.pager = {
650
651
  wo.pager_startPage = p.page;
651
652
  wo.pager_size = p.size;
652
653
  c.$table.trigger('applyWidgets');
654
+ if (table.isUpdating) {
655
+ c.$table.trigger('updateComplete');
656
+ }
653
657
 
654
658
  },
655
659
 
@@ -680,15 +684,19 @@ tsp = ts.pager = {
680
684
  });
681
685
  },
682
686
 
683
- moveToPage: function(table, p, flag) {
687
+ moveToPage: function(table, p, pageMoved) {
684
688
  if ( p.isDisabled ) { return; }
685
689
  var c = table.config,
686
690
  l = p.last,
687
691
  pg = Math.min( p.totalPages, p.filteredPages );
688
692
  if ( p.page < 0 ) { p.page = 0; }
689
693
  if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
690
- // don't allow rendering multiple times on the same page/size/totalpages/filters/sorts
691
- if ( l.page === p.page && l.size === p.size && l.totalPages === p.totalPages &&
694
+ // fixes issue where one current filter is [] and the other is ['','',''],
695
+ // making the next if comparison think the filters as different. Fixes #202.
696
+ l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
697
+ p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
698
+ // don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
699
+ if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
692
700
  (l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
693
701
  l.sortList === (c.sortList || []).join(',') ) {
694
702
  return;
@@ -701,7 +709,7 @@ tsp = ts.pager = {
701
709
  size : p.size,
702
710
  // fixes #408; modify sortList otherwise it auto-updates
703
711
  sortList : (c.sortList || []).join(','),
704
- totalPages : p.totalPages,
712
+ totalRows : p.totalRows,
705
713
  currentFilters : p.currentFilters || []
706
714
  };
707
715
  if (p.ajax) {
@@ -710,8 +718,11 @@ tsp = ts.pager = {
710
718
  tsp.renderTable(table, c.rowsCopy);
711
719
  }
712
720
  $.data(table, 'pagerLastPage', p.page);
713
- if (p.initialized && flag !== false) {
721
+ if (p.initialized && pageMoved !== false) {
714
722
  c.$table.trigger('pageMoved', c);
723
+ if (!p.ajax && table.isUpdating) {
724
+ c.$table.trigger('updateComplete');
725
+ }
715
726
  }
716
727
  },
717
728
 
@@ -800,6 +811,8 @@ tsp = ts.pager = {
800
811
  tsp.moveToPage(table, p, true);
801
812
  // update display here in case all rows are removed
802
813
  tsp.updatePageDisplay(table, c, false);
814
+ } else {
815
+ tsp.moveToPage(table, p, true);
803
816
  }
804
817
  }
805
818
 
@@ -41,14 +41,14 @@
41
41
  }
42
42
 
43
43
  /* since bootstrap (table-striped) uses nth-child(), we just use this to add a zebra stripe color */
44
- .tablesorter-bootstrap tr.odd td {
44
+ .tablesorter-bootstrap > tbody > tr.odd > td {
45
45
  background-color: #f9f9f9;
46
46
  }
47
- .tablesorter-bootstrap tbody > .odd:hover > td,
48
- .tablesorter-bootstrap tbody > .even:hover > td {
47
+ .tablesorter-bootstrap > tbody > tr.odd:hover > td,
48
+ .tablesorter-bootstrap > tbody > tr.even:hover > td {
49
49
  background-color: #f5f5f5;
50
50
  }
51
- .tablesorter-bootstrap tr.even td {
51
+ .tablesorter-bootstrap > tbody > tr.even > td {
52
52
  background-color: #fff;
53
53
  }
54
54
 
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.10.3
4
+ version: 1.10.4
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-02-23 00:00:00.000000000 Z
12
+ date: 2014-03-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -39,7 +39,7 @@ extensions: []
39
39
  extra_rdoc_files: []
40
40
  files:
41
41
  - MIT-LICENSE
42
- - README.markdown
42
+ - README.md
43
43
  - Rakefile
44
44
  - lib/jquery-tablesorter.rb
45
45
  - lib/jquery-tablesorter/engine.rb
@@ -99,6 +99,7 @@ files:
99
99
  - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js
100
100
  - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js
101
101
  - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js
102
+ - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js
102
103
  - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js
103
104
  - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-repeatheaders.js
104
105
  - vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js
@@ -135,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  version: '0'
136
137
  requirements: []
137
138
  rubyforge_project:
138
- rubygems_version: 2.2.0.rc.1
139
+ rubygems_version: 2.2.2
139
140
  signing_key:
140
141
  specification_version: 4
141
142
  summary: Simple integration of jquery-tablesorter into the asset pipeline.