jquery-tablesorter 1.14.1 → 1.15.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/README.md +2 -2
  3. data/lib/jquery-tablesorter/version.rb +1 -1
  4. data/vendor/assets/javascripts/jquery-tablesorter.js +1 -1
  5. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +5 -9
  6. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.dragtable.mod.js +1 -4
  7. data/vendor/assets/javascripts/jquery-tablesorter/{jquery.metadata.js → extras/jquery.metadata.js} +1 -0
  8. data/vendor/assets/javascripts/jquery-tablesorter/extras/jquery.quicksearch.js +8 -4
  9. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +116 -107
  10. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +232 -171
  11. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-file-type.js +1 -1
  12. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +1 -1
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-chart.js +2 -3
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columns.js +78 -0
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +14 -12
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +4 -4
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-formatter-html5.js +429 -0
  18. data/vendor/assets/javascripts/jquery-tablesorter/{jquery.tablesorter.widgets-filter-formatter.js → widgets/widget-filter-formatter-jui.js} +1 -381
  19. data/vendor/assets/javascripts/jquery-tablesorter/{jquery.tablesorter.widgets-filter-formatter-select2.js → widgets/widget-filter-formatter-select2.js} +0 -0
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +1307 -0
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-formatter.js +3 -3
  22. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +4 -4
  23. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +3 -3
  24. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +4 -8
  25. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +176 -0
  26. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +68 -0
  27. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +3 -3
  28. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +269 -0
  29. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +76 -0
  30. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +184 -0
  31. data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +1 -1
  32. data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +1 -1
  33. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +1 -1
  34. data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +1 -1
  35. data/vendor/assets/stylesheets/jquery-tablesorter/theme.dropbox.css +1 -1
  36. data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +1 -1
  37. data/vendor/assets/stylesheets/jquery-tablesorter/theme.grey.css +1 -1
  38. data/vendor/assets/stylesheets/jquery-tablesorter/theme.ice.css +1 -1
  39. data/vendor/assets/stylesheets/jquery-tablesorter/theme.jui.css +1 -1
  40. data/vendor/assets/stylesheets/jquery-tablesorter/theme.metro-dark.css +1 -1
  41. metadata +15 -7
@@ -1,74 +1,16 @@
1
- /*! tableSorter (FORK) 2.16+ widgets - updated 2/9/2015 (v2.19.1)
2
- *
3
- * Column Styles
4
- * Column Filters
5
- * Column Resizing
6
- * Sticky Header
7
- * UI Theme (generalized)
8
- * Save Sort
9
- * [ "columns", "filter", "resizable", "stickyHeaders", "uitheme", "saveSort" ]
10
- */
11
- /*jshint browser:true, jquery:true, unused:false, loopfunc:true */
12
- /*global jQuery: false, localStorage: false */
13
- ;(function ($, window) {
1
+ /*** This file is dynamically generated ***
2
+ █████▄ ▄████▄ █████▄ ▄████▄ ██████ ███████▄ ▄████▄ █████▄ ██ ██████ ██ ██
3
+ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
4
+ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀▀██
5
+ █████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
6
+ */
7
+ /*! tablesorter (FORK) widgets - updated 02-20-2015 (v2.20.1)*/
8
+ /* Includes: storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort */
9
+ /*! Widget: storage */
10
+ ;(function ($, window, document) {
14
11
  'use strict';
15
- var ts = $.tablesorter = $.tablesorter || {};
16
-
17
- ts.themes = {
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
38
- },
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
59
- }
60
- };
61
-
62
- $.extend(ts.css, {
63
- filterRow : 'tablesorter-filter-row', // filter
64
- filter : 'tablesorter-filter',
65
- wrapper : 'tablesorter-wrapper', // ui theme & resizable
66
- resizer : 'tablesorter-resizer', // resizable
67
- sticky : 'tablesorter-stickyHeader', // stickyHeader
68
- stickyVis : 'tablesorter-sticky-visible',
69
- stickyWrap: 'tablesorter-sticky-wrapper'
70
- });
71
12
 
13
+ var ts = $.tablesorter = $.tablesorter || {};
72
14
  // *** Store data in local storage, with a cookie fallback ***
73
15
  /* IE7 needs JSON library for JSON.stringify - (http://caniuse.com/#search=json)
74
16
  if you need it, then include https://github.com/douglascrockford/JSON-js
@@ -100,7 +42,7 @@ ts.storage = function(table, key, value, options) {
100
42
  url = options && options.url || $table.attr(options && options.page ||
101
43
  'data-table-page') || c && c.fixedUrl || window.location.pathname;
102
44
  // https://gist.github.com/paulirish/5558557
103
- if ("localStorage" in window) {
45
+ if ('localStorage' in window) {
104
46
  try {
105
47
  window.localStorage.setItem('_tmptest', 'temp');
106
48
  hasLocalStorage = true;
@@ -139,50 +81,62 @@ ts.storage = function(table, key, value, options) {
139
81
  }
140
82
  };
141
83
 
142
- // Add a resize event to table headers
143
- // **************************
144
- ts.addHeaderResizeEvent = function(table, disable, settings) {
145
- table = $(table)[0]; // make sure we're using a dom element
146
- var headers,
147
- defaults = {
148
- timer : 250
149
- },
150
- options = $.extend({}, defaults, settings),
151
- c = table.config,
152
- wo = c.widgetOptions,
153
- checkSizes = function(triggerEvent) {
154
- wo.resize_flag = true;
155
- headers = [];
156
- c.$headers.each(function() {
157
- var $header = $(this),
158
- sizes = $header.data('savedSizes') || [0,0], // fixes #394
159
- width = this.offsetWidth,
160
- height = this.offsetHeight;
161
- if (width !== sizes[0] || height !== sizes[1]) {
162
- $header.data('savedSizes', [ width, height ]);
163
- headers.push(this);
164
- }
165
- });
166
- if (headers.length && triggerEvent !== false) {
167
- c.$table.trigger('resize', [ headers ]);
168
- }
169
- wo.resize_flag = false;
170
- };
171
- checkSizes(false);
172
- clearInterval(wo.resize_timer);
173
- if (disable) {
174
- wo.resize_flag = false;
175
- return false;
84
+ })(jQuery, window, document);
85
+
86
+ /*! Widget: uitheme */
87
+ ;(function ($) {
88
+ 'use strict';
89
+ var ts = $.tablesorter = $.tablesorter || {};
90
+
91
+ ts.themes = {
92
+ 'bootstrap' : {
93
+ table : 'table table-bordered table-striped',
94
+ caption : 'caption',
95
+ // header class names
96
+ header : 'bootstrap-header', // give the header a gradient background (theme.bootstrap_2.css)
97
+ sortNone : '',
98
+ sortAsc : '',
99
+ sortDesc : '',
100
+ active : '', // applied when column is sorted
101
+ hover : '', // custom css required - a defined bootstrap style may not override other classes
102
+ // icon class names
103
+ icons : '', // add "icon-white" to make them white; this icon class is added to the <i> in the header
104
+ iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
105
+ iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
106
+ iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
107
+ filterRow : '', // filter row class
108
+ footerRow : '',
109
+ footerCells : '',
110
+ even : '', // even row zebra striping
111
+ odd : '' // odd row zebra striping
112
+ },
113
+ 'jui' : {
114
+ table : 'ui-widget ui-widget-content ui-corner-all', // table classes
115
+ caption : 'ui-widget-content',
116
+ // header class names
117
+ header : 'ui-widget-header ui-corner-all ui-state-default', // header classes
118
+ sortNone : '',
119
+ sortAsc : '',
120
+ sortDesc : '',
121
+ active : 'ui-state-active', // applied when column is sorted
122
+ hover : 'ui-state-hover', // hover class
123
+ // icon class names
124
+ icons : 'ui-icon', // icon class added to the <i> in the header
125
+ iconSortNone : 'ui-icon-carat-2-n-s', // class name added to icon when column is not sorted
126
+ iconSortAsc : 'ui-icon-carat-1-n', // class name added to icon when column has ascending sort
127
+ iconSortDesc : 'ui-icon-carat-1-s', // class name added to icon when column has descending sort
128
+ filterRow : '',
129
+ footerRow : '',
130
+ footerCells : '',
131
+ even : 'ui-widget-content', // even row zebra striping
132
+ odd : 'ui-state-default' // odd row zebra striping
176
133
  }
177
- wo.resize_timer = setInterval(function() {
178
- if (wo.resize_flag) { return; }
179
- checkSizes();
180
- }, options.timer);
181
134
  };
182
135
 
183
- // Widget: General UI theme
184
- // "uitheme" option in "widgetOptions"
185
- // **************************
136
+ $.extend(ts.css, {
137
+ wrapper : 'tablesorter-wrapper' // ui theme & resizable
138
+ });
139
+
186
140
  ts.addWidget({
187
141
  id: "uitheme",
188
142
  priority: 10,
@@ -312,10 +266,13 @@ ts.addWidget({
312
266
  }
313
267
  });
314
268
 
315
- // Widget: Column styles
316
- // "columns", "columns_thead" (true) and
317
- // "columns_tfoot" (true) options in "widgetOptions"
318
- // **************************
269
+ })(jQuery);
270
+
271
+ /*! Widget: columns */
272
+ ;(function ($) {
273
+ 'use strict';
274
+ var ts = $.tablesorter = $.tablesorter || {};
275
+
319
276
  ts.addWidget({
320
277
  id: "columns",
321
278
  priority: 30,
@@ -388,14 +345,25 @@ ts.addWidget({
388
345
  }
389
346
  });
390
347
 
391
- // Widget: filter
392
- // **************************
348
+ })(jQuery);
349
+
350
+ /*! Widget: filter */
351
+ ;(function ($) {
352
+ 'use strict';
353
+ var ts = $.tablesorter = $.tablesorter || {};
354
+
355
+ $.extend(ts.css, {
356
+ filterRow : 'tablesorter-filter-row',
357
+ filter : 'tablesorter-filter'
358
+ });
359
+
393
360
  ts.addWidget({
394
361
  id: "filter",
395
362
  priority: 50,
396
363
  options : {
397
364
  filter_childRows : false, // if true, filter includes child row content in the search
398
365
  filter_columnFilters : true, // if true, a filter will be added to the top of each table column
366
+ filter_columnAnyMatch: true, // if true, allows using "#:{query}" in AnyMatch searches (column:query)
399
367
  filter_cellFilter : '', // css class name added to the filter cell (string or array)
400
368
  filter_cssFilter : '', // css class name added to the filter row & each input in the row (tablesorter-filter is ALWAYS added)
401
369
  filter_defaultFilter : {}, // add a default column filter type "~{query}" to make fuzzy searches default; "{q1} AND {q2}" to make all searches use a logical AND.
@@ -434,7 +402,7 @@ ts.addWidget({
434
402
  $table
435
403
  .removeClass('hasFilters')
436
404
  // add .tsfilter namespace to all BUT search
437
- .unbind( $.trim(events) )
405
+ .unbind( events.replace(/\s+/g, ' ') )
438
406
  // remove the filter row even if refreshing, because the column might have been moved
439
407
  .find('.' + ts.css.filterRow).remove();
440
408
  if (refreshing) { return; }
@@ -661,7 +629,7 @@ ts.filter = {
661
629
  }
662
630
 
663
631
  txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '.split(' ').join(c.namespace + 'filter ');
664
- c.$table.bind( $.trim(txt), function(event, filter) {
632
+ c.$table.bind( txt, function(event, filter) {
665
633
  val = (wo.filter_hideEmpty && $.isEmptyObject(c.cache) && !(c.delayInit && event.type === 'appendCache'));
666
634
  // hide filter row using the "filtered" class name
667
635
  c.$table.find('.' + ts.css.filterRow).toggleClass(wo.filter_filteredRow, val ); // fixes #450
@@ -754,8 +722,8 @@ ts.filter = {
754
722
  // show processing icon
755
723
  if (c.showProcessing) {
756
724
  c.$table
757
- .unbind( $.trim('filterStart filterEnd '.split(' ').join(c.namespace + 'filter ')) )
758
- .bind( $.trim('filterStart filterEnd '.split(' ').join(c.namespace + 'filter ')), function(event, columns) {
725
+ .unbind( ('filterStart filterEnd '.split(' ').join(c.namespace + 'filter ')).replace(/\s+/g, ' ') )
726
+ .bind( 'filterStart filterEnd '.split(' ').join(c.namespace + 'filter '), function(event, columns) {
759
727
  // only add processing to certain columns to all columns
760
728
  $header = (columns) ? c.$table.find('.' + ts.css.header).filter('[data-column]').filter(function() {
761
729
  return columns[$(this).data('column')] !== '';
@@ -769,8 +737,8 @@ ts.filter = {
769
737
 
770
738
  // add default values
771
739
  c.$table
772
- .unbind( $.trim('tablesorter-initialized pagerBeforeInitialized '.split(' ').join(c.namespace + 'filter ')) )
773
- .bind( $.trim('tablesorter-initialized pagerBeforeInitialized '.split(' ').join(c.namespace + 'filter ')), function() {
740
+ .unbind( ('tablesorter-initialized pagerBeforeInitialized '.split(' ').join(c.namespace + 'filter ')).replace(/\s+/g, ' ') )
741
+ .bind( 'tablesorter-initialized pagerBeforeInitialized '.split(' ').join(c.namespace + 'filter '), function() {
774
742
  // redefine "wo" as it does not update properly inside this callback
775
743
  var wo = this.config.widgetOptions;
776
744
  filters = ts.filter.setDefaults(table, c, wo) || [];
@@ -942,7 +910,7 @@ ts.filter = {
942
910
  $el
943
911
  // use data attribute instead of jQuery data since the head is cloned without including the data/binding
944
912
  .attr('data-lastSearchTime', new Date().getTime())
945
- .unbind( $.trim('keypress keyup search change '.split(' ').join(c.namespace + 'filter ')) )
913
+ .unbind( ('keypress keyup search change '.split(' ').join(c.namespace + 'filter ')).replace(/\s+/g, ' ') )
946
914
  // include change for select - fixes #473
947
915
  .bind('keyup' + c.namespace + 'filter', function(event) {
948
916
  $(this).attr('data-lastSearchTime', new Date().getTime());
@@ -963,7 +931,7 @@ ts.filter = {
963
931
  // change event = no delay; last true flag tells getFilters to skip newest timed input
964
932
  ts.filter.searching( table, true, true );
965
933
  })
966
- .bind( $.trim('search change keypress '.split(' ').join(c.namespace + 'filter ')), function(event){
934
+ .bind( 'search change keypress '.split(' ').join(c.namespace + 'filter '), function(event){
967
935
  var column = $(this).data('column');
968
936
  // don't allow "change" event to process if the input value is the same - fixes #685
969
937
  if (event.which === 13 || event.type === 'search' || event.type === 'change' && this.value !== c.lastSearch[column]) {
@@ -1094,9 +1062,12 @@ ts.filter = {
1094
1062
  return val;
1095
1063
  },
1096
1064
  getLatestSearch: function( $input ) {
1097
- return $input.sort(function(a, b) {
1098
- return $(b).attr('data-lastSearchTime') - $(a).attr('data-lastSearchTime');
1099
- });
1065
+ if ($input) {
1066
+ return $input.sort(function(a, b) {
1067
+ return $(b).attr('data-lastSearchTime') - $(a).attr('data-lastSearchTime');
1068
+ });
1069
+ }
1070
+ return $();
1100
1071
  },
1101
1072
  multipleColumns: function( c, $input ) {
1102
1073
  // look for multiple columns "1-3,4-6,8" in data-column
@@ -1106,7 +1077,7 @@ ts.filter = {
1106
1077
  // & don't target "all" column inputs if they don't exist
1107
1078
  targets = wo.filter_initialized || !$input.filter(wo.filter_anyColumnSelector).length,
1108
1079
  columns = [],
1109
- val = $.trim( ts.filter.getLatestSearch( $input ).attr('data-column') );
1080
+ val = $.trim( ts.filter.getLatestSearch( $input ).attr('data-column') || '' );
1110
1081
  // process column range
1111
1082
  if ( targets && /-/.test( val ) ) {
1112
1083
  ranges = val.match( /(\d+)\s*-\s*(\d+)/g );
@@ -1146,13 +1117,13 @@ ts.filter = {
1146
1117
  },
1147
1118
  findRows: function(table, filters, combinedFilters) {
1148
1119
  if (table.config.lastCombinedFilter === combinedFilters || !table.config.widgetOptions.filter_initialized) { return; }
1149
- var len, $rows, rowIndex, tbodyIndex, $tbody, $cells, $cell, columnIndex,
1120
+ var len, norm_rows, $rows, rowIndex, tbodyIndex, $tbody, $cells, $cell, columnIndex,
1150
1121
  childRow, lastSearch, hasSelect, matches, result, showRow, time, val, indx,
1151
1122
  notFiltered, searchFiltered, filterMatched, excludeMatch, fxn, ffxn,
1123
+ query, injected, res, id,
1152
1124
  regex = ts.filter.regex,
1153
1125
  c = table.config,
1154
1126
  wo = c.widgetOptions,
1155
- $tbodies = c.$table.children('tbody'), // target all tbodies #568
1156
1127
  // data object passed to filters; anyMatch is a flag for the filters
1157
1128
  data = { anyMatch: false },
1158
1129
  // anyMatch really screws up with these types of filters
@@ -1176,14 +1147,14 @@ ts.filter = {
1176
1147
  // combindedFilters are undefined on init
1177
1148
  combinedFilters = (filters || []).join('');
1178
1149
 
1179
- for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
1180
- if ($tbodies.eq(tbodyIndex).hasClass(c.cssInfoBlock || ts.css.info)) { continue; } // ignore info blocks, issue #264
1181
- $tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true);
1150
+ for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
1151
+ $tbody = ts.processTbody(table, c.$tbodies.eq(tbodyIndex), true);
1182
1152
  // skip child rows & widget added (removable) rows - fixes #448 thanks to @hempel!
1183
1153
  // $rows = $tbody.children('tr').not(c.selectorRemove);
1184
1154
  columnIndex = c.columns;
1185
1155
  // convert stored rows into a jQuery object
1186
- $rows = $( $.map(c.cache[tbodyIndex].normalized, function(el){ return el[columnIndex].$row.get(); }) );
1156
+ norm_rows = c.cache[tbodyIndex].normalized;
1157
+ $rows = $( $.map(norm_rows, function(el){ return el[columnIndex].$row.get(); }) );
1187
1158
 
1188
1159
  if (combinedFilters === '' || wo.filter_serversideFiltering) {
1189
1160
  $rows.removeClass(wo.filter_filteredRow).not('.' + c.cssChildRow).show();
@@ -1191,6 +1162,33 @@ ts.filter = {
1191
1162
  // filter out child rows
1192
1163
  $rows = $rows.not('.' + c.cssChildRow);
1193
1164
  len = $rows.length;
1165
+
1166
+ if ( (wo.filter_$anyMatch && wo.filter_$anyMatch.length) || typeof filters[c.columns] !== 'undefined' ) {
1167
+ data.anyMatchFlag = true;
1168
+ data.anyMatchFilter = wo.filter_$anyMatch && ts.filter.getLatestSearch( wo.filter_$anyMatch ).val() || ( '' + filters[c.columns] ) || '';
1169
+ if (wo.filter_columnAnyMatch) {
1170
+ // specific columns search
1171
+ query = data.anyMatchFilter.split( ts.filter.regex.andSplit );
1172
+ injected = false;
1173
+ for (indx = 0; indx < query.length; indx++) {
1174
+ res = query[indx].split(':');
1175
+ if ( res.length > 1 ) {
1176
+ // make the column a one-based index ( non-developers start counting from one :P )
1177
+ id = parseInt( res[0], 10 ) - 1;
1178
+ if ( id >= 0 && id < c.columns ) { // if id is an integer
1179
+ filters[id] = res[1];
1180
+ query.splice(indx, 1);
1181
+ indx--;
1182
+ injected = true;
1183
+ }
1184
+ }
1185
+ }
1186
+ if (injected) {
1187
+ data.anyMatchFilter = query.join(' && ');
1188
+ }
1189
+ }
1190
+ }
1191
+
1194
1192
  // optimize searching only through already filtered rows - see #313
1195
1193
  searchFiltered = wo.filter_searchFiltered;
1196
1194
  lastSearch = c.lastSearch || c.$table.data('lastSearch') || [];
@@ -1220,9 +1218,7 @@ ts.filter = {
1220
1218
  if (c.debug) {
1221
1219
  ts.log( "Searching through " + ( searchFiltered && notFiltered < len ? notFiltered : "all" ) + " rows" );
1222
1220
  }
1223
- if ((wo.filter_$anyMatch && wo.filter_$anyMatch.length) || filters[c.columns]) {
1224
- data.anyMatchFlag = true;
1225
- data.anyMatchFilter = wo.filter_$anyMatch && ts.filter.getLatestSearch( wo.filter_$anyMatch ).val() || filters[c.columns] || '';
1221
+ if (data.anyMatchFlag) {
1226
1222
  if (c.sortLocaleCompare) {
1227
1223
  // replace accents
1228
1224
  data.anyMatchFilter = ts.replaceAccents(data.anyMatchFilter);
@@ -1240,7 +1236,7 @@ ts.filter = {
1240
1236
  // loop through the rows
1241
1237
  for (rowIndex = 0; rowIndex < len; rowIndex++) {
1242
1238
 
1243
- data.cacheArray = c.cache[tbodyIndex].normalized[rowIndex];
1239
+ data.cacheArray = norm_rows[rowIndex];
1244
1240
 
1245
1241
  childRow = $rows[rowIndex].className;
1246
1242
  // skip child rows & already filtered rows
@@ -1264,7 +1260,7 @@ ts.filter = {
1264
1260
  if (data.parsed[i]) {
1265
1261
  txt = data.cacheArray[i];
1266
1262
  } else {
1267
- txt = this.getAttribute( c.textAttribute ) || this.textContent || $(this).text();
1263
+ txt = this ? this.getAttribute( c.textAttribute ) || this.textContent || $(this).text() : '';
1268
1264
  txt = $.trim( wo.filter_ignoreCase ? txt.toLowerCase() : txt );
1269
1265
  if (c.sortLocaleCompare) {
1270
1266
  txt = ts.replaceAccents(txt);
@@ -1320,7 +1316,7 @@ ts.filter = {
1320
1316
  data.exact = data.cache;
1321
1317
  } else {
1322
1318
  val = $cells[columnIndex];
1323
- result = $.trim( val.getAttribute( c.textAttribute ) || val.textContent || $cells.eq(columnIndex).text() );
1319
+ result = val ? $.trim( val.getAttribute( c.textAttribute ) || val.textContent || $cells.eq(columnIndex).text() ) : '';
1324
1320
  data.exact = c.sortLocaleCompare ? ts.replaceAccents(result) : result; // issue #405
1325
1321
  }
1326
1322
  data.iExact = !regex.type.test(typeof data.exact) && wo.filter_ignoreCase ? data.exact.toLocaleLowerCase() : data.exact;
@@ -1488,26 +1484,23 @@ ts.filter = {
1488
1484
  var rowIndex, tbodyIndex, len, row, cache, cell,
1489
1485
  c = table.config,
1490
1486
  wo = c.widgetOptions,
1491
- $tbodies = c.$table.children('tbody'),
1492
1487
  arry = [];
1493
- for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
1494
- if (!$tbodies.eq(tbodyIndex).hasClass(c.cssInfoBlock)) {
1495
- cache = c.cache[tbodyIndex];
1496
- len = c.cache[tbodyIndex].normalized.length;
1497
- // loop through the rows
1498
- for (rowIndex = 0; rowIndex < len; rowIndex++) {
1499
- // get cached row from cache.row (old) or row data object (new; last item in normalized array)
1500
- row = cache.row ? cache.row[rowIndex] : cache.normalized[rowIndex][c.columns].$row[0];
1501
- // check if has class filtered
1502
- if (onlyAvail && row.className.match(wo.filter_filteredRow)) { continue; }
1503
- // get non-normalized cell content
1504
- if (wo.filter_useParsedData || c.parsers[column].parsed || c.$headers.filter('[data-column="' + column + '"]:last').hasClass('filter-parsed')) {
1505
- arry.push( '' + cache.normalized[rowIndex][column] );
1506
- } else {
1507
- cell = row.cells[column];
1508
- if (cell) {
1509
- arry.push( $.trim( cell.getAttribute( c.textAttribute ) || cell.textContent || $(cell).text() ) );
1510
- }
1488
+ for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
1489
+ cache = c.cache[tbodyIndex];
1490
+ len = c.cache[tbodyIndex].normalized.length;
1491
+ // loop through the rows
1492
+ for (rowIndex = 0; rowIndex < len; rowIndex++) {
1493
+ // get cached row from cache.row (old) or row data object (new; last item in normalized array)
1494
+ row = cache.row ? cache.row[rowIndex] : cache.normalized[rowIndex][c.columns].$row[0];
1495
+ // check if has class filtered
1496
+ if (onlyAvail && row.className.match(wo.filter_filteredRow)) { continue; }
1497
+ // get non-normalized cell content
1498
+ if (wo.filter_useParsedData || c.parsers[column].parsed || c.$headers.filter('[data-column="' + column + '"]:last').hasClass('filter-parsed')) {
1499
+ arry.push( '' + cache.normalized[rowIndex][column] );
1500
+ } else {
1501
+ cell = row.cells[column];
1502
+ if (cell) {
1503
+ arry.push( $.trim( cell.getAttribute( c.textAttribute ) || cell.textContent || $(cell).text() ) );
1511
1504
  }
1512
1505
  }
1513
1506
  }
@@ -1660,8 +1653,60 @@ ts.setFilters = function(table, filter, apply, skipFirst) {
1660
1653
  return !!valid;
1661
1654
  };
1662
1655
 
1663
- // Widget: Sticky headers
1664
- // based on this awesome article:
1656
+ })(jQuery);
1657
+
1658
+ /*! Widget: stickyHeaders */
1659
+ ;(function ($, window) {
1660
+ 'use strict';
1661
+ var ts = $.tablesorter = $.tablesorter || {};
1662
+
1663
+ $.extend(ts.css, {
1664
+ sticky : 'tablesorter-stickyHeader', // stickyHeader
1665
+ stickyVis : 'tablesorter-sticky-visible',
1666
+ stickyWrap: 'tablesorter-sticky-wrapper'
1667
+ });
1668
+
1669
+ // Add a resize event to table headers
1670
+ ts.addHeaderResizeEvent = function(table, disable, settings) {
1671
+ table = $(table)[0]; // make sure we're using a dom element
1672
+ var headers,
1673
+ defaults = {
1674
+ timer : 250
1675
+ },
1676
+ options = $.extend({}, defaults, settings),
1677
+ c = table.config,
1678
+ wo = c.widgetOptions,
1679
+ checkSizes = function(triggerEvent) {
1680
+ wo.resize_flag = true;
1681
+ headers = [];
1682
+ c.$headers.each(function() {
1683
+ var $header = $(this),
1684
+ sizes = $header.data('savedSizes') || [0,0], // fixes #394
1685
+ width = this.offsetWidth,
1686
+ height = this.offsetHeight;
1687
+ if (width !== sizes[0] || height !== sizes[1]) {
1688
+ $header.data('savedSizes', [ width, height ]);
1689
+ headers.push(this);
1690
+ }
1691
+ });
1692
+ if (headers.length && triggerEvent !== false) {
1693
+ c.$table.trigger('resize', [ headers ]);
1694
+ }
1695
+ wo.resize_flag = false;
1696
+ };
1697
+ checkSizes(false);
1698
+ clearInterval(wo.resize_timer);
1699
+ if (disable) {
1700
+ wo.resize_flag = false;
1701
+ return false;
1702
+ }
1703
+ wo.resize_timer = setInterval(function() {
1704
+ if (wo.resize_flag) { return; }
1705
+ checkSizes();
1706
+ }, options.timer);
1707
+ };
1708
+
1709
+ // Sticky headers based on this awesome article:
1665
1710
  // http://css-tricks.com/13465-persistent-headers/
1666
1711
  // and https://github.com/jmosbech/StickyTableHeaders by Jonas Mosbech
1667
1712
  // **************************
@@ -1777,7 +1822,7 @@ ts.addWidget({
1777
1822
  // update sticky header class names to match real header after sorting
1778
1823
  $table
1779
1824
  .addClass('hasStickyHeaders')
1780
- .bind( $.trim('pagerComplete' + namespace), function() {
1825
+ .bind('pagerComplete' + namespace, function() {
1781
1826
  resizeHeader();
1782
1827
  });
1783
1828
 
@@ -1796,8 +1841,8 @@ ts.addWidget({
1796
1841
 
1797
1842
  // make it sticky!
1798
1843
  $xScroll.add($yScroll)
1799
- .unbind( $.trim('scroll resize '.split(' ').join( namespace )) )
1800
- .bind( $.trim('scroll resize '.split(' ').join( namespace )), function(event) {
1844
+ .unbind( ('scroll resize '.split(' ').join( namespace )).replace(/\s+/g, ' ') )
1845
+ .bind('scroll resize '.split(' ').join( namespace ), function(event) {
1801
1846
  if (!$table.is(':visible')) { return; } // fixes #278
1802
1847
  // Detect nested tables - fixes #724
1803
1848
  nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
@@ -1838,7 +1883,7 @@ ts.addWidget({
1838
1883
  // look for filter widget
1839
1884
  if ($table.hasClass('hasFilters') && wo.filter_columnFilters) {
1840
1885
  // scroll table into view after filtering, if sticky header is active - #482
1841
- $table.bind( $.trim('filterEnd' + namespace), function() {
1886
+ $table.bind('filterEnd' + namespace, function() {
1842
1887
  // $(':focus') needs jQuery 1.6+
1843
1888
  var $td = $(document.activeElement).closest('td'),
1844
1889
  column = $td.parent().children().index($td);
@@ -1866,19 +1911,29 @@ ts.addWidget({
1866
1911
  var namespace = c.namespace + 'stickyheaders ';
1867
1912
  c.$table
1868
1913
  .removeClass('hasStickyHeaders')
1869
- .unbind( $.trim('pagerComplete filterEnd '.split(' ').join(namespace)) )
1914
+ .unbind( ('pagerComplete filterEnd '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
1870
1915
  .next('.' + ts.css.stickyWrap).remove();
1871
1916
  if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
1872
1917
  $(window)
1873
1918
  .add(wo.stickyHeaders_xScroll)
1874
1919
  .add(wo.stickyHeaders_yScroll)
1875
1920
  .add(wo.stickyHeaders_attachTo)
1876
- .unbind( $.trim('scroll resize '.split(' ').join(namespace)) );
1921
+ .unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') );
1877
1922
  ts.addHeaderResizeEvent(table, false);
1878
1923
  }
1879
1924
  });
1880
1925
 
1881
- // Add Column resizing widget
1926
+ })(jQuery, window);
1927
+
1928
+ /*! Widget: resizable */
1929
+ ;(function ($, window) {
1930
+ 'use strict';
1931
+ var ts = $.tablesorter = $.tablesorter || {};
1932
+
1933
+ $.extend(ts.css, {
1934
+ resizer : 'tablesorter-resizer' // resizable
1935
+ });
1936
+
1882
1937
  // this widget saves the column widths if
1883
1938
  // $.tablesorter.storage function is included
1884
1939
  // **************************
@@ -2045,7 +2100,13 @@ ts.resizableReset = function(table, nosave) {
2045
2100
  });
2046
2101
  };
2047
2102
 
2048
- // Save table sort widget
2103
+ })(jQuery, window);
2104
+
2105
+ /*! Widget: saveSort */
2106
+ ;(function ($) {
2107
+ 'use strict';
2108
+ var ts = $.tablesorter = $.tablesorter || {};
2109
+
2049
2110
  // this widget saves the last sort only if the
2050
2111
  // saveSort widget option is true AND the
2051
2112
  // $.tablesorter.storage function is included
@@ -2108,4 +2169,4 @@ ts.addWidget({
2108
2169
  }
2109
2170
  });
2110
2171
 
2111
- })(jQuery, window);
2172
+ })(jQuery);