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,4 +1,4 @@
1
- /*! tableSorter (FORK) 2.16+ widgets - updated 12/22/2014 (v2.18.4)
1
+ /*! tableSorter (FORK) 2.16+ widgets - updated 2/7/2015 (v2.19.0)
2
2
  *
3
3
  * Column Styles
4
4
  * Column Filters
@@ -11,41 +11,51 @@
11
11
  /*jshint browser:true, jquery:true, unused:false, loopfunc:true */
12
12
  /*global jQuery: false, localStorage: false */
13
13
  ;(function ($, window) {
14
- "use strict";
14
+ 'use strict';
15
15
  var ts = $.tablesorter = $.tablesorter || {};
16
16
 
17
17
  ts.themes = {
18
- "bootstrap" : {
19
- table : 'table table-bordered table-striped',
20
- caption : 'caption',
21
- header : 'bootstrap-header', // give the header a gradient background
22
- footerRow : '',
23
- footerCells: '',
24
- icons : '', // add "icon-white" to make them white; this icon class is added to the <i> in the header
25
- sortNone : 'bootstrap-icon-unsorted',
26
- sortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up',
27
- sortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down',
28
- active : '', // applied when column is sorted
29
- hover : '', // use custom css here - bootstrap class may not override it
30
- filterRow : '', // filter row class
31
- even : '', // even row zebra striping
32
- odd : '' // odd row zebra striping
18
+ 'bootstrap' : {
19
+ table : 'table table-bordered table-striped',
20
+ caption : 'caption',
21
+ // header class names
22
+ header : 'bootstrap-header', // give the header a gradient background (theme.bootstrap_2.css)
23
+ sortNone : '',
24
+ sortAsc : '',
25
+ sortDesc : '',
26
+ active : '', // applied when column is sorted
27
+ hover : '', // custom css required - a defined bootstrap style may not override other classes
28
+ // icon class names
29
+ icons : '', // add "icon-white" to make them white; this icon class is added to the <i> in the header
30
+ iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
31
+ iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
32
+ iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
33
+ filterRow : '', // filter row class
34
+ footerRow : '',
35
+ footerCells : '',
36
+ even : '', // even row zebra striping
37
+ odd : '' // odd row zebra striping
33
38
  },
34
- "jui" : {
35
- table : 'ui-widget ui-widget-content ui-corner-all', // table classes
36
- caption : 'ui-widget-content',
37
- header : 'ui-widget-header ui-corner-all ui-state-default', // header classes
38
- footerRow : '',
39
- footerCells: '',
40
- icons : 'ui-icon', // icon class added to the <i> in the header
41
- sortNone : 'ui-icon-carat-2-n-s',
42
- sortAsc : 'ui-icon-carat-1-n',
43
- sortDesc : 'ui-icon-carat-1-s',
44
- active : 'ui-state-active', // applied when column is sorted
45
- hover : 'ui-state-hover', // hover class
46
- filterRow : '',
47
- even : 'ui-widget-content', // even row zebra striping
48
- odd : 'ui-state-default' // odd row zebra striping
39
+ 'jui' : {
40
+ table : 'ui-widget ui-widget-content ui-corner-all', // table classes
41
+ caption : 'ui-widget-content',
42
+ // header class names
43
+ header : 'ui-widget-header ui-corner-all ui-state-default', // header classes
44
+ sortNone : '',
45
+ sortAsc : '',
46
+ sortDesc : '',
47
+ active : 'ui-state-active', // applied when column is sorted
48
+ hover : 'ui-state-hover', // hover class
49
+ // icon class names
50
+ icons : 'ui-icon', // icon class added to the <i> in the header
51
+ iconSortNone : 'ui-icon-carat-2-n-s', // class name added to icon when column is not sorted
52
+ iconSortAsc : 'ui-icon-carat-1-n', // class name added to icon when column has ascending sort
53
+ iconSortDesc : 'ui-icon-carat-1-s', // class name added to icon when column has descending sort
54
+ filterRow : '',
55
+ footerRow : '',
56
+ footerCells : '',
57
+ even : 'ui-widget-content', // even row zebra striping
58
+ odd : 'ui-state-default' // odd row zebra striping
49
59
  }
50
60
  };
51
61
 
@@ -100,13 +110,13 @@ ts.storage = function(table, key, value, options) {
100
110
  // *** get value ***
101
111
  if ($.parseJSON) {
102
112
  if (hasLocalStorage) {
103
- values = $.parseJSON(localStorage[key] || '{}');
113
+ values = $.parseJSON(localStorage[key] || 'null') || {};
104
114
  } else {
105
115
  // old browser, using cookies
106
116
  cookies = document.cookie.split(/[;\s|=]/);
107
117
  // add one to get from the key to the value
108
118
  cookieIndex = $.inArray(key, cookies) + 1;
109
- values = (cookieIndex !== 0) ? $.parseJSON(cookies[cookieIndex] || '{}') : {};
119
+ values = (cookieIndex !== 0) ? $.parseJSON(cookies[cookieIndex] || 'null') || {} : {};
110
120
  }
111
121
  }
112
122
  // allow value to be an empty string too
@@ -132,7 +142,7 @@ ts.storage = function(table, key, value, options) {
132
142
  // Add a resize event to table headers
133
143
  // **************************
134
144
  ts.addHeaderResizeEvent = function(table, disable, settings) {
135
- table = $(table)[0]; // make sure we're usig a dom element
145
+ table = $(table)[0]; // make sure we're using a dom element
136
146
  var headers,
137
147
  defaults = {
138
148
  timer : 250
@@ -177,33 +187,42 @@ ts.addWidget({
177
187
  id: "uitheme",
178
188
  priority: 10,
179
189
  format: function(table, c, wo) {
180
- var i, time, classes, $header, $icon, $tfoot, $h, oldtheme, oldremove,
190
+ var i, hdr, icon, time, $header, $icon, $tfoot, $h, oldtheme, oldremove, oldIconRmv, hasOldTheme,
181
191
  themesAll = ts.themes,
182
- $table = c.$table,
183
- $headers = c.$headers,
192
+ $table = c.$table.add( c.$extraTables ),
193
+ $headers = c.$headers.add( c.$extraHeaders ),
184
194
  theme = c.theme || 'jui',
185
- themes = themesAll[theme] || themesAll.jui,
186
- remove = [ themes.sortNone, themes.sortDesc, themes.sortAsc, themes.active ].join( ' ' );
195
+ themes = themesAll[theme] || {},
196
+ remove = $.trim( [ themes.sortNone, themes.sortDesc, themes.sortAsc, themes.active ].join( ' ' ) ),
197
+ iconRmv = $.trim( [ themes.iconSortNone, themes.iconSortDesc, themes.iconSortAsc ].join( ' ' ) );
187
198
  if (c.debug) { time = new Date(); }
188
199
  // initialization code - run once
189
- if (!$table.hasClass('tablesorter-' + theme) || c.theme !== c.appliedTheme || !table.hasInitialized) {
190
- oldtheme = themes[c.appliedTheme] || {};
191
- oldremove = oldtheme ? [ oldtheme.sortNone, oldtheme.sortDesc, oldtheme.sortAsc, oldtheme.active ].join( ' ' ) : '';
192
- if (oldtheme) {
193
- wo.zebra[0] = wo.zebra[0].replace(' ' + oldtheme.even, '');
194
- wo.zebra[1] = wo.zebra[1].replace(' ' + oldtheme.odd, '');
200
+ if (!$table.hasClass('tablesorter-' + theme) || c.theme !== c.appliedTheme || !wo.uitheme_applied) {
201
+ wo.uitheme_applied = true;
202
+ oldtheme = themesAll[c.appliedTheme] || {};
203
+ hasOldTheme = !$.isEmptyObject(oldtheme);
204
+ oldremove = hasOldTheme ? [ oldtheme.sortNone, oldtheme.sortDesc, oldtheme.sortAsc, oldtheme.active ].join( ' ' ) : '',
205
+ oldIconRmv = hasOldTheme ? [ oldtheme.iconSortNone, oldtheme.iconSortDesc, oldtheme.iconSortAsc ].join( ' ' ) : '';
206
+ if (hasOldTheme) {
207
+ wo.zebra[0] = $.trim( ' ' + wo.zebra[0].replace(' ' + oldtheme.even, '') );
208
+ wo.zebra[1] = $.trim( ' ' + wo.zebra[1].replace(' ' + oldtheme.odd, '') );
209
+ c.$tbodies.children().removeClass( [oldtheme.even, oldtheme.odd].join(' ') );
195
210
  }
196
211
  // update zebra stripes
197
- if (themes.even !== '') { wo.zebra[0] += ' ' + themes.even; }
198
- if (themes.odd !== '') { wo.zebra[1] += ' ' + themes.odd; }
212
+ if (themes.even) { wo.zebra[0] += ' ' + themes.even; }
213
+ if (themes.odd) { wo.zebra[1] += ' ' + themes.odd; }
199
214
  // add caption style
200
- $table.children('caption').removeClass(oldtheme.caption).addClass(themes.caption);
215
+ $table.children('caption')
216
+ .removeClass(oldtheme.caption || '')
217
+ .addClass(themes.caption);
201
218
  // add table/footer class names
202
219
  $tfoot = $table
203
220
  // remove other selected themes
204
- .removeClass( c.appliedTheme ? 'tablesorter-' + ( c.appliedTheme || '' ) : '' )
205
- .addClass('tablesorter-' + theme + ' ' + themes.table) // add theme widget class name
221
+ .removeClass( (c.appliedTheme ? 'tablesorter-' + (c.appliedTheme || '') : '') + ' ' + (oldtheme.table || '') )
222
+ .addClass('tablesorter-' + theme + ' ' + (themes.table || '')) // add theme widget class name
206
223
  .children('tfoot');
224
+ c.appliedTheme = c.theme;
225
+
207
226
  if ($tfoot.length) {
208
227
  $tfoot
209
228
  // if oldtheme.footerRow or oldtheme.footerCells are undefined, all class names are removed
@@ -212,43 +231,59 @@ ts.addWidget({
212
231
  }
213
232
  // update header classes
214
233
  $headers
215
- .add(c.$extraHeaders)
216
- .removeClass(oldtheme.header + ' ' + oldtheme.hover + ' ' + oldremove)
234
+ .removeClass( (hasOldTheme ? [oldtheme.header, oldtheme.hover, oldremove].join(' ') : '') || '' )
217
235
  .addClass(themes.header)
218
236
  .not('.sorter-false')
237
+ .unbind('mouseenter.tsuitheme mouseleave.tsuitheme')
219
238
  .bind('mouseenter.tsuitheme mouseleave.tsuitheme', function(event) {
220
239
  // toggleClass with switch added in jQuery 1.3
221
- $(this)[ event.type === 'mouseenter' ? 'addClass' : 'removeClass' ](themes.hover);
240
+ $(this)[ event.type === 'mouseenter' ? 'addClass' : 'removeClass' ](themes.hover || '');
222
241
  });
223
- if (!$headers.find('.' + ts.css.wrapper).length) {
224
- // Firefox needs this inner div to position the resizer correctly
225
- $headers.wrapInner('<div class="' + ts.css.wrapper + '" style="position:relative;height:100%;width:100%"></div>');
226
- }
242
+
243
+ $headers.each(function(){
244
+ var $this = $(this);
245
+ if (!$this.find('.' + ts.css.wrapper).length) {
246
+ // Firefox needs this inner div to position the icon & resizer correctly
247
+ $this.wrapInner('<div class="' + ts.css.wrapper + '" style="position:relative;height:100%;width:100%"></div>');
248
+ }
249
+ });
227
250
  if (c.cssIcon) {
228
251
  // if c.cssIcon is '', then no <i> is added to the header
229
- $headers.find('.' + ts.css.icon).removeClass(oldtheme.icons + ' ' + oldremove).addClass(themes.icons);
252
+ $headers
253
+ .find('.' + ts.css.icon)
254
+ .removeClass(hasOldTheme ? [oldtheme.icons, oldIconRmv].join(' ') : '')
255
+ .addClass(themes.icons || '');
230
256
  }
231
257
  if ($table.hasClass('hasFilters')) {
232
- $table.children('thead').children('.' + ts.css.filterRow).removeClass(oldtheme.filterRow).addClass(themes.filterRow);
258
+ $table.children('thead').children('.' + ts.css.filterRow)
259
+ .removeClass(hasOldTheme ? oldtheme.filterRow || '' : '')
260
+ .addClass(themes.filterRow || '');
233
261
  }
234
- c.appliedTheme = c.theme;
235
262
  }
236
263
  for (i = 0; i < c.columns; i++) {
237
264
  $header = c.$headers.add(c.$extraHeaders).not('.sorter-false').filter('[data-column="' + i + '"]');
238
- $icon = (ts.css.icon) ? $header.find('.' + ts.css.icon) : $header;
265
+ $icon = (ts.css.icon) ? $header.find('.' + ts.css.icon) : $();
239
266
  $h = $headers.not('.sorter-false').filter('[data-column="' + i + '"]:last');
240
267
  if ($h.length) {
268
+ $header.removeClass(remove);
269
+ $icon.removeClass(iconRmv);
241
270
  if ($h[0].sortDisabled) {
242
271
  // no sort arrows for disabled columns!
243
- $header.removeClass(remove);
244
- $icon.removeClass(remove + ' ' + themes.icons);
272
+ $icon.removeClass(themes.icons || '');
245
273
  } else {
246
- classes = ($header.hasClass(ts.css.sortAsc)) ?
247
- themes.sortAsc :
248
- ($header.hasClass(ts.css.sortDesc)) ? themes.sortDesc :
249
- $header.hasClass(ts.css.header) ? themes.sortNone : '';
250
- $header[classes === themes.sortNone ? 'removeClass' : 'addClass'](themes.active);
251
- $icon.removeClass(remove).addClass(classes);
274
+ hdr = themes.sortNone;
275
+ icon = themes.iconSortNone;
276
+ if ($h.hasClass(ts.css.sortAsc)) {
277
+ hdr = [themes.sortAsc, themes.active].join(' ');
278
+ icon = themes.iconSortAsc;
279
+ } else if ($h.hasClass(ts.css.sortDesc)) {
280
+ hdr = [themes.sortDesc, themes.active].join(' ');
281
+ icon = themes.iconSortDesc;
282
+ }
283
+ $h
284
+ .addClass(hdr)
285
+ .find('.' + ts.css.icon)
286
+ .addClass(icon || '');
252
287
  }
253
288
  }
254
289
  }
@@ -256,21 +291,24 @@ ts.addWidget({
256
291
  ts.benchmark("Applying " + theme + " theme", time);
257
292
  }
258
293
  },
259
- remove: function(table, c) {
294
+ remove: function(table, c, wo, refreshing) {
295
+ if (!wo.uitheme_applied) { return; }
260
296
  var $table = c.$table,
261
- theme = c.theme || 'jui',
297
+ theme = c.appliedTheme || 'jui',
262
298
  themes = ts.themes[ theme ] || ts.themes.jui,
263
299
  $headers = $table.children('thead').children(),
264
- remove = themes.sortNone + ' ' + themes.sortDesc + ' ' + themes.sortAsc;
265
- $table
266
- .removeClass('tablesorter-' + theme + ' ' + themes.table)
267
- .find(ts.css.header).removeClass(themes.header);
300
+ remove = themes.sortNone + ' ' + themes.sortDesc + ' ' + themes.sortAsc,
301
+ iconRmv = themes.iconSortNone + ' ' + themes.iconSortDesc + ' ' + themes.iconSortAsc;
302
+ $table.removeClass('tablesorter-' + theme + ' ' + themes.table);
303
+ wo.uitheme_applied = false;
304
+ if (refreshing) { return; }
305
+ $table.find(ts.css.header).removeClass(themes.header);
268
306
  $headers
269
307
  .unbind('mouseenter.tsuitheme mouseleave.tsuitheme') // remove hover
270
308
  .removeClass(themes.hover + ' ' + remove + ' ' + themes.active)
271
- .find('.' + ts.css.filterRow)
309
+ .filter('.' + ts.css.filterRow)
272
310
  .removeClass(themes.filterRow);
273
- $headers.find('.' + ts.css.icon).removeClass(themes.icons);
311
+ $headers.find('.' + ts.css.icon).removeClass(themes.icons + ' ' + iconRmv);
274
312
  }
275
313
  });
276
314
 
@@ -388,7 +426,7 @@ ts.addWidget({
388
426
  ts.filter.init(table, c, wo);
389
427
  }
390
428
  },
391
- remove: function(table, c, wo) {
429
+ remove: function(table, c, wo, refreshing) {
392
430
  var tbodyIndex, $tbody,
393
431
  $table = c.$table,
394
432
  $tbodies = c.$tbodies;
@@ -396,7 +434,9 @@ ts.addWidget({
396
434
  .removeClass('hasFilters')
397
435
  // add .tsfilter namespace to all BUT search
398
436
  .unbind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter '))
437
+ // remove the filter row even if refreshing, because the column might have been moved
399
438
  .find('.' + ts.css.filterRow).remove();
439
+ if (refreshing) { return; }
400
440
  for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
401
441
  $tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
402
442
  $tbody.children().removeClass(wo.filter_filteredRow).show();
@@ -619,8 +659,11 @@ ts.filter = {
619
659
  ts.filter.buildRow(table, c, wo);
620
660
  }
621
661
 
622
- c.$table.bind('addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter '), function(event, filter) {
623
- c.$table.find('.' + ts.css.filterRow).toggle( !(wo.filter_hideEmpty && $.isEmptyObject(c.cache) && !(c.delayInit && event.type === 'appendCache')) ); // fixes #450
662
+ txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter ');
663
+ c.$table.bind(txt, function(event, filter) {
664
+ val = (wo.filter_hideEmpty && $.isEmptyObject(c.cache) && !(c.delayInit && event.type === 'appendCache'));
665
+ // hide filter row using the "filtered" class name
666
+ c.$table.find('.' + ts.css.filterRow).toggleClass(wo.filter_filteredRow, val ); // fixes #450
624
667
  if ( !/(search|filter)/.test(event.type) ) {
625
668
  event.stopPropagation();
626
669
  ts.filter.buildDefault(table, true);
@@ -1216,7 +1259,8 @@ ts.filter = {
1216
1259
  if (data.parsed[i]) {
1217
1260
  txt = data.cacheArray[i];
1218
1261
  } else {
1219
- txt = wo.filter_ignoreCase ? $(this).text().toLowerCase() : $(this).text();
1262
+ txt = this.getAttribute( c.textAttribute ) || this.textContent || $(this).text();
1263
+ txt = $.trim( wo.filter_ignoreCase ? txt.toLowerCase() : txt );
1220
1264
  if (c.sortLocaleCompare) {
1221
1265
  txt = ts.replaceAccents(txt);
1222
1266
  }
@@ -1270,9 +1314,9 @@ ts.filter = {
1270
1314
  if (wo.filter_useParsedData || data.parsed[columnIndex]) {
1271
1315
  data.exact = data.cache;
1272
1316
  } else {
1273
- // using older or original tablesorter
1274
- data.exact = $.trim( $cells.eq(columnIndex).text() );
1275
- data.exact = c.sortLocaleCompare ? ts.replaceAccents(data.exact) : data.exact; // issue #405
1317
+ val = $cells[columnIndex];
1318
+ result = $.trim( val.getAttribute( c.textAttribute ) || val.textContent || $cells.eq(columnIndex).text() );
1319
+ data.exact = c.sortLocaleCompare ? ts.replaceAccents(result) : result; // issue #405
1276
1320
  }
1277
1321
  data.iExact = !regex.type.test(typeof data.exact) && wo.filter_ignoreCase ? data.exact.toLocaleLowerCase() : data.exact;
1278
1322
  result = showRow; // if showRow is true, show that row
@@ -1280,9 +1324,10 @@ ts.filter = {
1280
1324
  // in case select filter option has a different value vs text "a - z|A through Z"
1281
1325
  ffxn = wo.filter_columnFilters ?
1282
1326
  c.$filters.add(c.$externalFilters).filter('[data-column="'+ columnIndex + '"]').find('select option:selected').attr('data-function-name') || '' : '';
1283
-
1284
1327
  // replace accents - see #357
1285
- data.filter = c.sortLocaleCompare ? ts.replaceAccents(data.filter) : data.filter;
1328
+ if (c.sortLocaleCompare) {
1329
+ data.filter = ts.replaceAccents(data.filter);
1330
+ }
1286
1331
 
1287
1332
  val = true;
1288
1333
  if (wo.filter_defaultFilter && regex.iQuery.test( ts.getColumnData( table, wo.filter_defaultFilter, columnIndex ) || '')) {
@@ -1357,6 +1402,7 @@ ts.filter = {
1357
1402
  }, 0);
1358
1403
  },
1359
1404
  getOptionSource: function(table, column, onlyAvail) {
1405
+ table = $(table)[0];
1360
1406
  var cts,
1361
1407
  c = table.config,
1362
1408
  wo = c.widgetOptions,
@@ -1433,6 +1479,7 @@ ts.filter = {
1433
1479
  }
1434
1480
  },
1435
1481
  getOptions: function(table, column, onlyAvail) {
1482
+ table = $(table)[0];
1436
1483
  var rowIndex, tbodyIndex, len, row, cache, cell,
1437
1484
  c = table.config,
1438
1485
  wo = c.widgetOptions,
@@ -1454,7 +1501,7 @@ ts.filter = {
1454
1501
  } else {
1455
1502
  cell = row.cells[column];
1456
1503
  if (cell) {
1457
- arry.push( $.trim( cell.textContent || cell.innerText || $(cell).text() ) );
1504
+ arry.push( $.trim( cell.getAttribute( c.textAttribute ) || cell.textContent || $(cell).text() ) );
1458
1505
  }
1459
1506
  }
1460
1507
  }
@@ -1602,7 +1649,7 @@ ts.setFilters = function(table, filter, apply, skipFirst) {
1602
1649
  // ensure new set filters are applied, even if the search is the same
1603
1650
  c.lastCombinedFilter = null;
1604
1651
  c.lastSearch = [];
1605
- ts.filter.searching(c.$table[0], filter, skipFirst);
1652
+ ts.filter.searching(c.table, filter, skipFirst);
1606
1653
  c.$table.trigger('filterFomatterUpdate');
1607
1654
  }
1608
1655
  return !!valid;
@@ -1703,6 +1750,13 @@ ts.addWidget({
1703
1750
  setWidth( $table, $stickyTable );
1704
1751
  setWidth( $header, $stickyCells );
1705
1752
  };
1753
+ // save stickyTable element to config
1754
+ // it is also saved to wo.$sticky
1755
+ if (c.$extraTables && c.$extraTables.length) {
1756
+ c.$extraTables.add($stickyTable);
1757
+ } else {
1758
+ c.$extraTables = $stickyTable;
1759
+ }
1706
1760
  // fix clone ID, if it exists - fixes #271
1707
1761
  if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
1708
1762
  // clear out cloned table, except for sticky header
@@ -1810,11 +1864,11 @@ ts.addWidget({
1810
1864
  .unbind( 'pagerComplete filterEnd '.split(' ').join(namespace) )
1811
1865
  .next('.' + ts.css.stickyWrap).remove();
1812
1866
  if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
1813
- // don't unbind if any table on the page still has stickyheaders applied
1814
- if (!$('.hasStickyHeaders').length) {
1815
- $(window).add(wo.stickyHeaders_xScroll).add(wo.stickyHeaders_yScroll).add(wo.stickyHeaders_attachTo)
1816
- .unbind( 'scroll resize '.split(' ').join(namespace) );
1817
- }
1867
+ $(window)
1868
+ .add(wo.stickyHeaders_xScroll)
1869
+ .add(wo.stickyHeaders_yScroll)
1870
+ .add(wo.stickyHeaders_attachTo)
1871
+ .unbind( 'scroll resize '.split(' ').join(namespace) );
1818
1872
  ts.addHeaderResizeEvent(table, false);
1819
1873
  }
1820
1874
  });
@@ -1974,7 +2028,7 @@ ts.resizableReset = function(table, nosave) {
1974
2028
  if (table && c) {
1975
2029
  c.$headers.each(function(i){
1976
2030
  $t = $(this);
1977
- if (wo.resizable_widths[i]) {
2031
+ if (wo.resizable_widths && wo.resizable_widths[i]) {
1978
2032
  $t.css('width', wo.resizable_widths[i]);
1979
2033
  } else if (!$t.hasClass('resizable-false')) {
1980
2034
  // don't clear the width of any column that is not resizable
@@ -2042,7 +2096,8 @@ ts.addWidget({
2042
2096
  }
2043
2097
  }
2044
2098
  },
2045
- remove: function(table) {
2099
+ remove: function(table, c) {
2100
+ c.$table.removeClass('hasSaveSort');
2046
2101
  // clear storage
2047
2102
  if (ts.storage) { ts.storage( table, 'tablesorter-savesort', '' ); }
2048
2103
  }
@@ -1,13 +1,12 @@
1
- /*! Duration parser
2
- */
1
+ /*! Duration parser */
3
2
  /*jshint jquery:true, unused:false */
4
3
  ;(function($){
5
- "use strict";
4
+ 'use strict';
6
5
 
7
6
  // If any number > 9999, then set table.config.durationLength = 5
8
7
  // The below regex matches this duration example: 1y 23d 12h 44m 9s
9
8
  $.tablesorter.addParser({
10
- id: "duration",
9
+ id: 'duration',
11
10
  is: function() {
12
11
  return false;
13
12
  },
@@ -34,7 +33,35 @@
34
33
  }
35
34
  return duration;
36
35
  },
37
- type: "text"
36
+ type: 'text'
37
+ });
38
+
39
+ /*! Countdown parser ( hh:mm:ss ) */
40
+ /* Added 2/7/2015 (v2.19.0) - see http://stackoverflow.com/a/27023733/145346 */
41
+ $.tablesorter.addParser({
42
+ id: 'countdown',
43
+ is: function () {
44
+ return false;
45
+ },
46
+ format: function ( text, table ) {
47
+ // change maxDigits to 4, if values go > 999
48
+ // or to 5 for values > 9999, etc.
49
+ var maxDigits = table.config.durationLength || 4,
50
+ // prefix contains leading zeros that are tacked
51
+ prefix = new Array( maxDigits + 1 ).join( '0' ),
52
+ // split time into blocks
53
+ blocks = text.split( /\s*:\s*/ ),
54
+ len = blocks.length,
55
+ result = [];
56
+ // add values in reverse, so if there is only one block
57
+ // ( e.g. '10' ), then it would be the time in seconds
58
+ while ( len ) {
59
+ result.push( ( prefix + ( blocks[ --len ] || 0 ) ).slice( -maxDigits ) );
60
+ }
61
+ // reverse the results and join them
62
+ return result.length ? result.reverse().join( '' ) : text;
63
+ },
64
+ type: 'text'
38
65
  });
39
66
 
40
67
  })(jQuery);