jquery-tablesorter 1.13.4 → 1.14.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +2 -2
  4. data/lib/jquery-tablesorter/version.rb +1 -1
  5. data/vendor/assets/images/jquery-tablesorter/dragtable-handle.png +0 -0
  6. data/vendor/assets/images/jquery-tablesorter/dragtable-handle.svg +7 -0
  7. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +58 -32
  8. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +605 -0
  9. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +161 -81
  10. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter-select2.js +41 -30
  11. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +151 -96
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-duration.js +32 -5
  13. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +21 -26
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +5 -4
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +2 -2
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +276 -0
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +64 -32
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +3 -2
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +11 -5
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-formatter.js +70 -0
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +13 -6
  22. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +7 -3
  23. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +70 -41
  24. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +2 -2
  25. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +4 -3
  26. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-repeatheaders.js +14 -12
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +68 -26
  28. data/vendor/assets/stylesheets/jquery-tablesorter/dragtable.mod.css +64 -0
  29. data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +3 -0
  30. data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +3 -0
  31. data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +3 -0
  32. data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +3 -0
  33. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +3 -0
  34. data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +3 -0
  35. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +3 -0
  36. data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +3 -0
  37. data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +3 -0
  38. data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +3 -0
  39. data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +3 -0
  40. data/vendor/assets/stylesheets/jquery-tablesorter/theme.metro-dark.css +3 -0
  41. metadata +8 -2
@@ -1,5 +1,5 @@
1
1
  /**!
2
- * TableSorter (FORK) 2.18.4 - Client-side table sorting with ease!
2
+ * TableSorter (FORK) 2.19.0 - Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
5
5
  * Copyright (c) 2007 Christian Bach
@@ -15,8 +15,16 @@
15
15
  * @contributor Rob Garrison/https://github.com/Mottie/tablesorter
16
16
  */
17
17
  /*jshint browser:true, jquery:true, unused:false, expr: true */
18
- /*global console:false, alert:false */
19
- !(function($) {
18
+ /*global console:false, alert:false, require:false, define:false, module:false */
19
+ (function(factory) {
20
+ if (typeof define === 'function' && define.amd) {
21
+ define(['jquery'], factory);
22
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
23
+ module.exports = factory(require('jquery'));
24
+ } else {
25
+ factory(jQuery);
26
+ }
27
+ }(function($) {
20
28
  "use strict";
21
29
  $.extend({
22
30
  /*jshint supernew:true */
@@ -24,7 +32,7 @@
24
32
 
25
33
  var ts = this;
26
34
 
27
- ts.version = "2.18.4";
35
+ ts.version = "2.19.0";
28
36
 
29
37
  ts.parsers = [];
30
38
  ts.widgets = [];
@@ -48,6 +56,7 @@
48
56
  usNumberFormat : true, // false for German "1.234.567,89" or French "1 234 567,89"
49
57
  delayInit : false, // if false, the parsed table contents will not update until the first sort
50
58
  serverSideSorting: false, // if true, server-side sorting should be performed because client-side sorting will be disabled, but the ui and events will still be used.
59
+ resort : true, // default setting to trigger a resort after an "update", "addRows", "updateCell", etc has completed
51
60
 
52
61
  // *** sort options
53
62
  headers : {}, // set sorter, string, empty, locked order, sortInitialOrder, filter, etc.
@@ -62,10 +71,10 @@
62
71
  sortReset : false, // third click on the header will reset column to default - unsorted
63
72
  sortRestart : false, // restart sort to "sortInitialOrder" when clicking on previously unsorted columns
64
73
 
65
- emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero
74
+ emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero, emptyMax, emptyMin
66
75
  stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero
67
76
  textExtraction : 'basic', // text extraction method/function - function(node, table, cellIndex){}
68
- textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in textExtraction function)
77
+ textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in default textExtraction function)
69
78
  textSorter : null, // choose overall or specific column sorter function(a, b, direction, table, columnIndex) [alt: ts.sortText]
70
79
  numberSorter : null, // choose overall numeric sorter function(a, b, direction, maxColumnValue)
71
80
 
@@ -90,7 +99,7 @@
90
99
  cssProcessing : '', // processing icon applied to header during sort/filter
91
100
 
92
101
  cssChildRow : 'tablesorter-childRow', // class name indiciating that a row is to be attached to the its parent
93
- cssIcon : 'tablesorter-icon', // if this class exists, a <i> will be added to the header automatically
102
+ cssIcon : 'tablesorter-icon', // if this class does not exist, the {icon} will not be added from the headerTemplate
94
103
  cssIconNone : '', // class name added to the icon when there is no column sort
95
104
  cssIconAsc : '', // class name added to the icon when the column has an ascending sort
96
105
  cssIconDesc : '', // class name added to the icon when the column has a descending sort
@@ -112,8 +121,7 @@
112
121
  strings: {},
113
122
  parsers: []
114
123
 
115
- // deprecated; but retained for backwards compatibility
116
- // widgetZebra: { css: ["even", "odd"] }
124
+ // removed: widgetZebra: { css: ["even", "odd"] }
117
125
 
118
126
  };
119
127
 
@@ -123,6 +131,7 @@
123
131
  table : 'tablesorter',
124
132
  cssHasChild: 'tablesorter-hasChildRow',
125
133
  childRow : 'tablesorter-childRow',
134
+ colgroup : 'tablesorter-colgroup',
126
135
  header : 'tablesorter-header',
127
136
  headerRow : 'tablesorter-headerRow',
128
137
  headerIn : 'tablesorter-header-inner',
@@ -172,24 +181,23 @@
172
181
  }
173
182
 
174
183
  function getElementText(table, node, cellIndex) {
175
- if (!node) { return ""; }
176
- var te, c = table.config,
177
- t = c.textExtraction || '',
178
- text = "";
179
- if (t === "basic") {
180
- // check data-attribute first
181
- text = $(node).attr(c.textAttribute) || node.textContent || node.innerText || $(node).text() || "";
184
+ if (!node) { return ''; }
185
+ var te,
186
+ $node = $(node),
187
+ c = table.config,
188
+ t = c.textExtraction || '';
189
+ if (typeof(t) === 'string') {
190
+ // check data-attribute first when set to "basic"; don't use node.innerText - it's really slow!
191
+ return $.trim( (t === 'basic' ? $node.attr(c.textAttribute) || node.textContent : node.textContent ) || $node.text() || '' );
182
192
  } else {
183
- if (typeof(t) === "function") {
184
- text = t(node, table, cellIndex);
193
+ if (typeof(t) === 'function') {
194
+ return $.trim( t(node, table, cellIndex) );
185
195
  } else if (typeof (te = ts.getColumnData( table, t, cellIndex )) === 'function') {
186
- text = te(node, table, cellIndex);
187
- } else {
188
- // previous "simple" method
189
- text = node.textContent || node.innerText || $(node).text() || "";
196
+ return $.trim( te(node, table, cellIndex) );
190
197
  }
191
198
  }
192
- return $.trim(text);
199
+ // fallback
200
+ return $.trim( node.textContent || $node.text() || '' );
193
201
  }
194
202
 
195
203
  function detectParserForColumn(table, rows, rowIndex, cellIndex) {
@@ -242,7 +250,7 @@
242
250
  };
243
251
  while (j < len) {
244
252
  rows = tb[j].rows;
245
- if (rows[j]) {
253
+ if (rows.length) {
246
254
  l = c.columns; // rows[j].cells.length;
247
255
  for (i = 0; i < l; i++) {
248
256
  h = c.$headers.filter('[data-column="' + i + '"]:last');
@@ -457,9 +465,9 @@
457
465
  // save original header content
458
466
  c.headerContent[index] = $t.html();
459
467
  // if headerTemplate is empty, don't reformat the header cell
460
- if ( c.headerTemplate !== '' ) {
468
+ if ( c.headerTemplate !== '' && !$t.find('.' + ts.css.headerIn).length ) {
461
469
  // set up header template
462
- t = c.headerTemplate.replace(/\{content\}/g, $t.html()).replace(/\{icon\}/g, i);
470
+ t = c.headerTemplate.replace(/\{content\}/g, $t.html()).replace(/\{icon\}/g, $t.find('.' + ts.css.icon).length ? '' : i);
463
471
  if (c.onRenderTemplate) {
464
472
  h = c.onRenderTemplate.apply($t, [index, t]);
465
473
  if (h && typeof h === 'string') { t = h; } // only change t if something is returned
@@ -505,7 +513,7 @@
505
513
  buildParserCache(table);
506
514
  // rebuild the cache map
507
515
  buildCache(table);
508
- checkResort(c.$table, resort, callback);
516
+ checkResort(c, resort, callback);
509
517
  }
510
518
 
511
519
  function updateHeader(table) {
@@ -575,28 +583,13 @@
575
583
  c.$headers.not('.sorter-false').each(function(){
576
584
  var $this = $(this),
577
585
  nextSort = this.order[(this.count + 1) % (c.sortReset ? 3 : 2)],
578
- txt = $this.text() + ': ' +
586
+ txt = $.trim( $this.text() ) + ': ' +
579
587
  ts.language[ $this.hasClass(ts.css.sortAsc) ? 'sortAsc' : $this.hasClass(ts.css.sortDesc) ? 'sortDesc' : 'sortNone' ] +
580
588
  ts.language[ nextSort === 0 ? 'nextAsc' : nextSort === 1 ? 'nextDesc' : 'nextNone' ];
581
589
  $this.attr('aria-label', txt );
582
590
  });
583
591
  }
584
592
 
585
- // automatically add col group, and column sizes if set
586
- function fixColumnWidth(table) {
587
- var colgroup, overallWidth,
588
- c = table.config;
589
- if (c.widthFixed && c.$table.children('colgroup').length === 0) {
590
- colgroup = $('<colgroup>');
591
- overallWidth = $(table).width();
592
- // only add col for visible columns - fixes #371
593
- $(table.tBodies).not('.' + c.cssInfoBlock).find("tr:first").children(":visible").each(function() {
594
- colgroup.append($('<col>').css('width', parseInt(($(this).width()/overallWidth)*1000, 10)/10 + '%'));
595
- });
596
- c.$table.prepend(colgroup);
597
- }
598
- }
599
-
600
593
  function updateHeaderSortCount(table, list) {
601
594
  var s, t, o, col, primary,
602
595
  c = table.config,
@@ -821,27 +814,35 @@
821
814
  if (c.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time", sortTime); }
822
815
  }
823
816
 
824
- function resortComplete($table, callback){
825
- var table = $table[0];
826
- if (table.isUpdating) {
827
- $table.trigger('updateComplete', table);
817
+ function resortComplete(c, callback){
818
+ if (c.table.isUpdating) {
819
+ c.$table.trigger('updateComplete', c.table);
828
820
  }
829
821
  if ($.isFunction(callback)) {
830
- callback($table[0]);
822
+ callback(c.table);
831
823
  }
832
824
  }
833
825
 
834
- function checkResort($table, flag, callback) {
835
- var sl = $table[0].config.sortList;
826
+ function checkResort(c, resort, callback) {
827
+ var sl = $.isArray(resort) ? resort : c.sortList,
828
+ // if no resort parameter is passed, fallback to config.resort (true by default)
829
+ resrt = typeof resort === 'undefined' ? c.resort : resort;
836
830
  // don't try to resort if the table is still processing
837
831
  // this will catch spamming of the updateCell method
838
- if (flag !== false && !$table[0].isProcessing && sl.length) {
839
- $table.trigger("sorton", [sl, function(){
840
- resortComplete($table, callback);
841
- }, true]);
832
+ if (resrt !== false && !c.serverSideSorting && !c.table.isProcessing) {
833
+ if (sl.length) {
834
+ c.$table.trigger('sorton', [sl, function(){
835
+ resortComplete(c, callback);
836
+ }, true]);
837
+ } else {
838
+ c.$table.trigger('sortReset', [function(){
839
+ resortComplete(c, callback);
840
+ ts.applyWidget(c.table, false);
841
+ }]);
842
+ }
842
843
  } else {
843
- resortComplete($table, callback);
844
- ts.applyWidget($table[0], false);
844
+ resortComplete(c, callback);
845
+ ts.applyWidget(c.table, false);
845
846
  }
846
847
  }
847
848
 
@@ -865,7 +866,6 @@
865
866
  e.stopPropagation();
866
867
  table.isUpdating = true;
867
868
  ts.refreshWidgets(table, true, true);
868
- ts.restoreHeaders(table);
869
869
  buildHeaders(table);
870
870
  ts.bindEvents(table, c.$headers, true);
871
871
  bindMethods(table);
@@ -908,7 +908,18 @@
908
908
  // update column max value (ignore sign)
909
909
  c.cache[tbdy].colMax[icell] = Math.max(Math.abs(v) || 0, c.cache[tbdy].colMax[icell] || 0);
910
910
  }
911
- checkResort($table, resort, callback);
911
+ v = resort !== 'undefined' ? resort : c.resort;
912
+ if (v !== false) {
913
+ // widgets will be reapplied
914
+ checkResort(c, v, callback);
915
+ } else {
916
+ // don't reapply widgets is resort is false, just in case it causes
917
+ // problems with element focus
918
+ if ($.isFunction(callback)) {
919
+ callback(table);
920
+ }
921
+ c.$table.trigger('updateComplete', c.table);
922
+ }
912
923
  }
913
924
  })
914
925
  .bind("addRows" + c.namespace, function(e, $row, resort, callback) {
@@ -957,7 +968,7 @@
957
968
  c.cache[tbdy].normalized.push(cells);
958
969
  }
959
970
  // resort using current settings
960
- checkResort($table, resort, callback);
971
+ checkResort(c, resort, callback);
961
972
  }
962
973
  })
963
974
  .bind("updateComplete" + c.namespace, function(){
@@ -1020,7 +1031,7 @@
1020
1031
  })
1021
1032
  .bind("resetToLoadState" + c.namespace, function(){
1022
1033
  // remove all widgets
1023
- ts.refreshWidgets(table, true, true);
1034
+ ts.removeWidget(table, true, false);
1024
1035
  // restore original settings; this clears out current settings, but does not clear
1025
1036
  // values saved to storage.
1026
1037
  c = $.extend(true, ts.defaults, c.originalSettings);
@@ -1112,7 +1123,7 @@
1112
1123
  buildHeaders(table);
1113
1124
  // fixate columns if the users supplies the fixedWidth option
1114
1125
  // do this after theme has been applied
1115
- fixColumnWidth(table);
1126
+ ts.fixColumnWidth(table);
1116
1127
  // try to auto detect column type, and store in tables config
1117
1128
  buildParserCache(table);
1118
1129
  // start total row count at zero
@@ -1168,6 +1179,28 @@
1168
1179
  if (typeof c.initialized === 'function') { c.initialized(table); }
1169
1180
  };
1170
1181
 
1182
+ // automatically add a colgroup with col elements set to a percentage width
1183
+ ts.fixColumnWidth = function(table) {
1184
+ table = $(table)[0];
1185
+ var overallWidth, percent,
1186
+ c = table.config,
1187
+ colgroup = c.$table.children('colgroup');
1188
+ // remove plugin-added colgroup, in case we need to refresh the widths
1189
+ if (colgroup.length && colgroup.hasClass(ts.css.colgroup)) {
1190
+ colgroup.remove();
1191
+ }
1192
+ if (c.widthFixed && c.$table.children('colgroup').length === 0) {
1193
+ colgroup = $('<colgroup class="' + ts.css.colgroup + '">');
1194
+ overallWidth = c.$table.width();
1195
+ // only add col for visible columns - fixes #371
1196
+ $(table.tBodies).not('.' + c.cssInfoBlock).find('tr:first').children(':visible').each(function() {
1197
+ percent = parseInt( ( $(this).width() / overallWidth ) * 1000, 10 ) / 10 + '%';
1198
+ colgroup.append( $('<col>').css('width', percent) );
1199
+ });
1200
+ c.$table.prepend(colgroup);
1201
+ }
1202
+ };
1203
+
1171
1204
  ts.getColumnData = function(table, obj, indx, getCell, $headers){
1172
1205
  if (typeof obj === 'undefined' || obj === null) { return; }
1173
1206
  table = $(table)[0];
@@ -1331,13 +1364,15 @@
1331
1364
 
1332
1365
  // restore headers
1333
1366
  ts.restoreHeaders = function(table){
1334
- var c = $(table)[0].config;
1367
+ var $cell,
1368
+ c = $(table)[0].config;
1335
1369
  // don't use c.$headers here in case header cells were swapped
1336
1370
  c.$table.find(c.selectorHeaders).each(function(i){
1371
+ $cell = $(this);
1337
1372
  // only restore header cells if it is wrapped
1338
1373
  // because this is also used by the updateAll method
1339
- if ($(this).find('.' + ts.css.headerIn).length){
1340
- $(this).html( c.headerContent[i] );
1374
+ if ($cell.find('.' + ts.css.headerIn).length){
1375
+ $cell.html( c.headerContent[i] );
1341
1376
  }
1342
1377
  });
1343
1378
  };
@@ -1346,7 +1381,7 @@
1346
1381
  table = $(table)[0];
1347
1382
  if (!table.hasInitialized) { return; }
1348
1383
  // remove all widgets
1349
- ts.refreshWidgets(table, true, true);
1384
+ ts.removeWidget(table, true, false);
1350
1385
  var $t = $(table), c = table.config,
1351
1386
  $h = $t.find('thead:first'),
1352
1387
  $r = $h.find('tr.' + ts.css.headerRow).removeClass(ts.css.headerRow + ' ' + c.cssHeaderRow),
@@ -1577,7 +1612,7 @@
1577
1612
  }
1578
1613
  };
1579
1614
 
1580
- ts.applyWidget = function(table, init) {
1615
+ ts.applyWidget = function(table, init, callback) {
1581
1616
  table = $(table)[0]; // in case this is called externally
1582
1617
  var c = table.config,
1583
1618
  wo = c.widgetOptions,
@@ -1640,6 +1675,10 @@
1640
1675
  }
1641
1676
  }
1642
1677
  });
1678
+ // callback executed on init only
1679
+ if (!init && typeof callback === 'function') {
1680
+ callback(table);
1681
+ }
1643
1682
  }
1644
1683
  setTimeout(function(){
1645
1684
  table.isApplyingWidgets = false;
@@ -1651,24 +1690,63 @@
1651
1690
  }
1652
1691
  };
1653
1692
 
1693
+ ts.removeWidget = function(table, name, refreshing){
1694
+ table = $(table)[0];
1695
+ // if name === true, add all widgets from $.tablesorter.widgets
1696
+ if (name === true) {
1697
+ name = [];
1698
+ $.each( ts.widgets, function(i, w){
1699
+ if (w && w.id) {
1700
+ name.push( w.id );
1701
+ }
1702
+ });
1703
+ } else {
1704
+ // name can be either an array of widgets names,
1705
+ // or a space/comma separated list of widget names
1706
+ name = ( $.isArray(name) ? name.join(',') : name || '' ).toLowerCase().split( /[\s,]+/ );
1707
+ }
1708
+ var i, widget, indx,
1709
+ c = table.config,
1710
+ len = name.length;
1711
+ for (i = 0; i < len; i++) {
1712
+ widget = ts.getWidgetById(name[i]);
1713
+ indx = $.inArray( name[i], c.widgets );
1714
+ if ( widget && 'remove' in widget ) {
1715
+ if (c.debug && indx >= 0) { log( 'Removing "' + name[i] + '" widget' ); }
1716
+ widget.remove(table, c, c.widgetOptions, refreshing);
1717
+ c.widgetInit[name[i]] = false;
1718
+ }
1719
+ // don't remove the widget from config.widget if refreshing
1720
+ if (indx >= 0 && refreshing !== true) {
1721
+ c.widgets.splice( indx, 1 );
1722
+ }
1723
+ }
1724
+ };
1725
+
1654
1726
  ts.refreshWidgets = function(table, doAll, dontapply) {
1655
1727
  table = $(table)[0]; // see issue #243
1656
- var i, c = table.config,
1728
+ var c = table.config,
1657
1729
  cw = c.widgets,
1658
- w = ts.widgets, l = w.length;
1659
- // remove previous widgets
1660
- for (i = 0; i < l; i++){
1661
- if ( w[i] && w[i].id && (doAll || $.inArray( w[i].id, cw ) < 0) ) {
1662
- if (c.debug) { log( 'Refeshing widgets: Removing "' + w[i].id + '"' ); }
1663
- // only remove widgets that have been initialized - fixes #442
1664
- if (w[i].hasOwnProperty('remove') && c.widgetInit[w[i].id]) {
1665
- w[i].remove(table, c, c.widgetOptions);
1666
- c.widgetInit[w[i].id] = false;
1667
- }
1730
+ list = [],
1731
+ callback = function(table){
1732
+ $(table).trigger('refreshComplete');
1733
+ };
1734
+ // remove widgets not defined in config.widgets, unless doAll is true
1735
+ $.each( ts.widgets, function(i, w){
1736
+ if (w && w.id && (doAll || $.inArray( w.id, cw ) < 0)) {
1737
+ list.push( w.id );
1668
1738
  }
1669
- }
1739
+ });
1740
+ ts.removeWidget( table, list.join(','), true );
1670
1741
  if (dontapply !== true) {
1671
- ts.applyWidget(table, doAll);
1742
+ // call widget init if
1743
+ ts.applyWidget(table, doAll || false, callback );
1744
+ if (doAll) {
1745
+ // apply widget format
1746
+ ts.applyWidget(table, false, callback);
1747
+ }
1748
+ } else {
1749
+ callback(table);
1672
1750
  }
1673
1751
  };
1674
1752
 
@@ -1928,7 +2006,8 @@
1928
2006
  });
1929
2007
  }
1930
2008
  },
1931
- remove: function(table, c, wo){
2009
+ remove: function(table, c, wo, refreshing){
2010
+ if (refreshing) { return; }
1932
2011
  var k, $tb,
1933
2012
  b = c.$tbodies,
1934
2013
  rmv = (wo.zebra || [ "even", "odd" ]).join(' ');
@@ -1940,4 +2019,5 @@
1940
2019
  }
1941
2020
  });
1942
2021
 
1943
- })(jQuery);
2022
+ return ts;
2023
+ }));
@@ -1,4 +1,4 @@
1
- /*! Filter widget select2 formatter function - updated 7/17/2014 (v2.17.5)
1
+ /*! Filter widget select2 formatter function - updated 2/7/2015 (v2.19.0)
2
2
  * requires: jQuery 1.7.2+, tableSorter (FORK) 2.16+, filter widget 2.16+ and select2 v3.4.6+ plugin
3
3
  */
4
4
  /*jshint browser:true, jquery:true, unused:false */
@@ -28,14 +28,14 @@ ts.filterFormatter.select2 = function($cell, indx, select2Def) {
28
28
  wo = c.widgetOptions,
29
29
  // Add a hidden input to hold the range values
30
30
  $input = $('<input class="filter" type="hidden">')
31
- .appendTo($cell)
32
- // hidden filter update namespace trigger by filter widget
33
- .bind('change' + c.namespace + 'filter', function(){
34
- var val = this.value;
35
- val = val.replace(/[/()$^]/g, '').split('|');
36
- $cell.find('.select2').select2('val', val);
37
- updateSelect2();
38
- }),
31
+ .appendTo($cell)
32
+ // hidden filter update namespace trigger by filter widget
33
+ .bind('change' + c.namespace + 'filter', function(){
34
+ var val = this.value;
35
+ val = val.replace(/[/()$^]/g, '').split('|');
36
+ $cell.find('.select2').select2('val', val);
37
+ updateSelect2();
38
+ }),
39
39
  $header = c.$headers.filter('[data-column="' + indx + '"]:last'),
40
40
  onlyAvail = $header.hasClass(wo.filter_onlyAvail),
41
41
  $shcell = [],
@@ -44,16 +44,27 @@ ts.filterFormatter.select2 = function($cell, indx, select2Def) {
44
44
 
45
45
  // this function updates the hidden input and adds the current values to the header cell text
46
46
  updateSelect2 = function() {
47
- var v = $cell.find('.select2').select2('val') || o.value || '';
47
+ var arry = false,
48
+ v = $cell.find('.select2').select2('val') || o.value || '';
49
+ // convert array to string
50
+ if ($.isArray(v)) {
51
+ arry = true;
52
+ v = v.join('\u0000');
53
+ }
54
+ // escape special regex characters (http://stackoverflow.com/a/9310752/145346)
55
+ v = v.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
56
+ // convert string back into an array
57
+ if (arry) {
58
+ v = v.split('\u0000');
59
+ }
48
60
  $input
49
- // add regex, so we filter exact numbers
50
- .val( $.isArray(v) && v.length && v.join('') !== '' ? '/(' + matchPrefix + (v || []).join(matchSuffix + '|' + matchPrefix) + matchSuffix + ')/' : '' )
51
- .trigger('search').end()
52
- .find('.select2').select2('val', v);
61
+ // add regex, so we filter exact numbers
62
+ .val( $.isArray(v) && v.length && v.join('') !== '' ? '/(' + matchPrefix + (v || []).join(matchSuffix + '|' + matchPrefix) + matchSuffix + ')/' : '' )
63
+ .trigger('search').end()
64
+ .find('.select2').select2('val', v);
53
65
  // update sticky header cell
54
66
  if ($shcell.length) {
55
- $shcell
56
- .find('.select2').select2('val', v);
67
+ $shcell.find('.select2').select2('val', v);
57
68
  }
58
69
  },
59
70
 
@@ -88,18 +99,18 @@ ts.filterFormatter.select2 = function($cell, indx, select2Def) {
88
99
 
89
100
  // add a select2 hidden input!
90
101
  $('<input class="select2 select2-' + indx + '" type="hidden" />')
91
- .val(o.value)
92
- .appendTo($cell)
93
- .select2(o)
94
- .bind('change', function(){
95
- updateSelect2();
96
- });
102
+ .val(o.value)
103
+ .appendTo($cell)
104
+ .select2(o)
105
+ .bind('change', function(){
106
+ updateSelect2();
107
+ });
97
108
 
98
109
  // update select2 from filter hidden input, in case of saved filters
99
110
  c.$table.bind('filterFomatterUpdate', function(){
100
111
  // value = '/(^x$|^y$)/' => 'x,y'
101
112
  var val = c.$table.data('lastSearch')[indx] || '';
102
- val = val.replace(/[/()$^]/g, '').split('|');
113
+ val = val.replace(/^\/\(\^?/,'').replace(/\$\|\^/g, '|').replace(/\$?\)\/$/g,'').split('|');
103
114
  $cell.find('.select2').select2('val', val);
104
115
  updateSelect2();
105
116
  ts.filter.formatterUpdated($cell, indx);
@@ -110,13 +121,13 @@ ts.filterFormatter.select2 = function($cell, indx, select2Def) {
110
121
  $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
111
122
  // add a select2!
112
123
  $('<input class="select2 select2-' + indx + '" type="hidden">')
113
- .val(o.value)
114
- .appendTo($shcell)
115
- .select2(o)
116
- .bind('change', function(){
117
- $cell.find('.select2').select2('val', $shcell.find('.select2').select2('val') );
118
- updateSelect2();
119
- });
124
+ .val(o.value)
125
+ .appendTo($shcell)
126
+ .select2(o)
127
+ .bind('change', function(){
128
+ $cell.find('.select2').select2('val', $shcell.find('.select2').select2('val') );
129
+ updateSelect2();
130
+ });
120
131
  if (o.cellText) {
121
132
  $shcell.prepend('<label>' + o.cellText + '</label>');
122
133
  }