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
@@ -49,7 +49,7 @@
49
49
  types = $.tablesorter.fileTypes.equivalents;
50
50
  if (!m) {
51
51
  // make a string to "quick" match the existing equivalents
52
- var t = [];
52
+ t = [];
53
53
  $.each(types, function(i,v){
54
54
  t.push(v);
55
55
  });
@@ -141,7 +141,7 @@
141
141
  return restoreValue();
142
142
  }
143
143
  // ignore change event if nothing changed
144
- if ($tar.val() !== $tar.data('ts-original-value')) {
144
+ if ($tar.val() !== $tar.data('ts-original-value') || e.target.type === 'checkbox') {
145
145
  $tar.data('ts-original-value', $tar.val());
146
146
  // pass undefined resort value so it falls back to config.resort setting
147
147
  $table.trigger('updateCell', [ $tar.closest('td'), undef, function(){
@@ -149,14 +149,13 @@
149
149
  },
150
150
 
151
151
  getRows: function(c, wo) {
152
- // the cache may not have a zero index if there are any "info-only" tbodies above the main tbody
153
- var cache = c.cache[0].normalized,
152
+ var norm_rows = c.cache[0].normalized,
154
153
  rows = [];
155
154
  chart_rows = [];
156
155
  chart_categories = [];
157
156
  chart_category = [];
158
157
 
159
- $.each(cache, function(indx, rowVal) {
158
+ $.each(norm_rows, function(indx, rowVal) {
160
159
  var i, txt,
161
160
  $tr = rowVal[c.columns].$row,
162
161
  $cells = $tr.children('th,td'),
@@ -0,0 +1,78 @@
1
+ /*! Widget: columns */
2
+ ;(function ($) {
3
+ 'use strict';
4
+ var ts = $.tablesorter = $.tablesorter || {};
5
+
6
+ ts.addWidget({
7
+ id: "columns",
8
+ priority: 30,
9
+ options : {
10
+ columns : [ "primary", "secondary", "tertiary" ]
11
+ },
12
+ format: function(table, c, wo) {
13
+ var $tbody, tbodyIndex, $rows, rows, $row, $cells, remove, indx,
14
+ $table = c.$table,
15
+ $tbodies = c.$tbodies,
16
+ sortList = c.sortList,
17
+ len = sortList.length,
18
+ // removed c.widgetColumns support
19
+ css = wo && wo.columns || [ "primary", "secondary", "tertiary" ],
20
+ last = css.length - 1;
21
+ remove = css.join(' ');
22
+ // check if there is a sort (on initialization there may not be one)
23
+ for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
24
+ $tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // detach tbody
25
+ $rows = $tbody.children('tr');
26
+ // loop through the visible rows
27
+ $rows.each(function() {
28
+ $row = $(this);
29
+ if (this.style.display !== 'none') {
30
+ // remove all columns class names
31
+ $cells = $row.children().removeClass(remove);
32
+ // add appropriate column class names
33
+ if (sortList && sortList[0]) {
34
+ // primary sort column class
35
+ $cells.eq(sortList[0][0]).addClass(css[0]);
36
+ if (len > 1) {
37
+ for (indx = 1; indx < len; indx++) {
38
+ // secondary, tertiary, etc sort column classes
39
+ $cells.eq(sortList[indx][0]).addClass( css[indx] || css[last] );
40
+ }
41
+ }
42
+ }
43
+ }
44
+ });
45
+ ts.processTbody(table, $tbody, false);
46
+ }
47
+ // add classes to thead and tfoot
48
+ rows = wo.columns_thead !== false ? ['thead tr'] : [];
49
+ if (wo.columns_tfoot !== false) {
50
+ rows.push('tfoot tr');
51
+ }
52
+ if (rows.length) {
53
+ $rows = $table.find( rows.join(',') ).children().removeClass(remove);
54
+ if (len) {
55
+ for (indx = 0; indx < len; indx++) {
56
+ // add primary. secondary, tertiary, etc sort column classes
57
+ $rows.filter('[data-column="' + sortList[indx][0] + '"]').addClass(css[indx] || css[last]);
58
+ }
59
+ }
60
+ }
61
+ },
62
+ remove: function(table, c, wo) {
63
+ var tbodyIndex, $tbody,
64
+ $tbodies = c.$tbodies,
65
+ remove = (wo.columns || [ "primary", "secondary", "tertiary" ]).join(' ');
66
+ c.$headers.removeClass(remove);
67
+ c.$table.children('tfoot').children('tr').children('th, td').removeClass(remove);
68
+ for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
69
+ $tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
70
+ $tbody.children('tr').each(function() {
71
+ $(this).children().removeClass(remove);
72
+ });
73
+ ts.processTbody(table, $tbody, false); // restore tbody
74
+ }
75
+ }
76
+ });
77
+
78
+ })(jQuery);
@@ -2,7 +2,7 @@
2
2
  * Requires a modern browser, tablesorter v2.8+
3
3
  */
4
4
  /*jshint jquery:true, unused:false */
5
- ;(function($){
5
+ ;(function($, window){
6
6
  'use strict';
7
7
 
8
8
  var ts = $.tablesorter;
@@ -59,8 +59,8 @@
59
59
  }
60
60
 
61
61
  $win
62
- .unbind( $.trim('scroll resize '.split(' ').join(namespace)) )
63
- .bind( $.trim('scroll resize '.split(' ').join(namespace)), function() {
62
+ .unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
63
+ .bind('scroll resize '.split(' ').join(namespace), function() {
64
64
  // make sure "wo" is current otherwise changes to widgetOptions
65
65
  // are not dynamic (like the add caption button in the demo)
66
66
  wo = c.widgetOptions;
@@ -126,20 +126,22 @@
126
126
  setTransform( $cells, finalY );
127
127
 
128
128
  });
129
- $table.unbind( $.trim('filterEnd' + namespace) ).bind( $.trim('filterEnd' + namespace), function() {
130
- if (wo.cssStickyHeaders_filteredToTop) {
131
- // scroll top of table into view
132
- window.scrollTo(0, $table.position().top);
133
- }
134
- });
129
+ $table
130
+ .unbind( ('filterEnd' + namespace).replace(/\s+/g, ' ') )
131
+ .bind('filterEnd' + namespace, function() {
132
+ if (wo.cssStickyHeaders_filteredToTop) {
133
+ // scroll top of table into view
134
+ window.scrollTo(0, $table.position().top);
135
+ }
136
+ });
135
137
 
136
138
  },
137
139
  remove: function(table, c, wo, refreshing) {
138
140
  if (refreshing) { return; }
139
141
  var namespace = c.namespace + 'cssstickyheader ';
140
- $(window).unbind( $.trim('scroll resize '.split(' ').join(namespace)) );
142
+ $(window).unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') );
141
143
  c.$table
142
- .unbind( $.trim('filterEnd scroll resize '.split(' ').join(namespace)) )
144
+ .unbind( ('filterEnd scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
143
145
  .add( c.$table.children('thead').children().children() )
144
146
  .children('thead, caption').css({
145
147
  'transform' : '',
@@ -149,4 +151,4 @@
149
151
  }
150
152
  });
151
153
 
152
- })(jQuery);
154
+ })(jQuery, window);
@@ -95,13 +95,13 @@ var tse = $.tablesorter.editable = {
95
95
 
96
96
  bindEvents: function( c, wo ) {
97
97
  c.$table
98
- .off( $.trim( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable' ) ) )
99
- .on( $.trim( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable' ) ), function() {
98
+ .off( ( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable' ) ).replace( /\s+/g, ' ' ) )
99
+ .on( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable' ), function() {
100
100
  tse.update( c, c.widgetOptions );
101
101
  });
102
102
 
103
103
  c.$tbodies
104
- .off( $.trim( 'mouseleave focus blur focusout keydown '.split( ' ' ).join( '.tseditable ' ) ) )
104
+ .off( ( 'mouseleave focus blur focusout keydown '.split( ' ' ).join( '.tseditable ' ) ).replace( /\s+/g, ' ' ) )
105
105
  .on( 'mouseleave.tseditable', function() {
106
106
  if ( c.$table.data( 'contentFocused' ) ) {
107
107
  // change to 'true' instead of element to allow focusout to process
@@ -140,7 +140,7 @@ var tse = $.tablesorter.editable = {
140
140
  }
141
141
  }
142
142
  })
143
- .on( $.trim( 'blur focusout keydown '.split( ' ' ).join( '.tseditable ' ) ), '[contenteditable]', function( e ) {
143
+ .on( 'blur focusout keydown '.split( ' ' ).join( '.tseditable ' ), '[contenteditable]', function( e ) {
144
144
  if ( !c.$table.data( 'contentFocused' ) ) { return; }
145
145
  var t, validate,
146
146
  valid = false,
@@ -0,0 +1,429 @@
1
+ /*! Filter widget formatter html5 functions *//* updated 7/17/2014 (v2.17.5)
2
+ * requires: tableSorter (FORK) 2.15+ and jQuery 1.4.3+
3
+ *
4
+ * html5Number (spinner)
5
+ * html5Range (slider)
6
+ * html5Color (color)
7
+ */
8
+ /*jshint browser:true, jquery:true, unused:false */
9
+ /*global jQuery: false */
10
+ ;(function($){
11
+ "use strict";
12
+
13
+ var ts = $.tablesorter || {},
14
+
15
+ // compare option selector class name (jQuery selector)
16
+ compareSelect = '.compare-select',
17
+
18
+
19
+ tsff = ts.filterFormatter = {
20
+
21
+ addCompare: function($cell, indx, options){
22
+ if (options.compare && $.isArray(options.compare) && options.compare.length > 1) {
23
+ var opt = '',
24
+ compareSelectClass = [ compareSelect.slice(1), ' ' + compareSelect.slice(1), '' ],
25
+ txt = options.cellText ? '<label class="' + compareSelectClass.join('-label') + indx + '">' + options.cellText + '</label>' : '';
26
+ $.each(options.compare, function(i, c){
27
+ opt += '<option ' + (options.selected === i ? 'selected' : '') + '>' + c + '</option>';
28
+ });
29
+ $cell
30
+ .wrapInner('<div class="' + compareSelectClass.join('-wrapper') + indx + '" />')
31
+ .prepend( txt + '<select class="' + compareSelectClass.join('') + indx + '" />' )
32
+ .find('select')
33
+ .append(opt);
34
+ }
35
+ },
36
+
37
+ updateCompare : function($cell, $input, o) {
38
+ var val = $input.val() || '',
39
+ num = val.replace(/\s*?[><=]\s*?/g, ''),
40
+ compare = val.match(/[><=]/g) || '';
41
+ if (o.compare) {
42
+ if ($.isArray(o.compare)){
43
+ compare = (compare || []).join('') || o.compare[o.selected || 0];
44
+ }
45
+ $cell.find(compareSelect).val( compare );
46
+ }
47
+ return [ val, num ];
48
+ },
49
+
50
+ /**********************\
51
+ HTML5 Number (spinner)
52
+ \**********************/
53
+ html5Number : function($cell, indx, def5Num) {
54
+ var t, o = $.extend({
55
+ value : 0,
56
+ min : 0,
57
+ max : 100,
58
+ step : 1,
59
+ delayed : true,
60
+ disabled : false,
61
+ addToggle : false,
62
+ exactMatch : false,
63
+ cellText : '',
64
+ compare : '',
65
+ skipTest: false
66
+ }, def5Num),
67
+
68
+ $input,
69
+ // test browser for HTML5 range support
70
+ $number = $('<input type="number" style="visibility:hidden;" value="test">').appendTo($cell),
71
+ // test if HTML5 number is supported - from Modernizr
72
+ numberSupported = o.skipTest || $number.attr('type') === 'number' && $number.val() !== 'test',
73
+ $shcell = [],
74
+ c = $cell.closest('table')[0].config,
75
+
76
+ updateNumber = function(delayed, notrigger){
77
+ var chkd = o.addToggle ? $cell.find('.toggle').is(':checked') : true,
78
+ v = $cell.find('.number').val(),
79
+ compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
80
+ searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
81
+ $input
82
+ // add equal to the beginning, so we filter exact numbers
83
+ .val( !o.addToggle || chkd ? (compare ? compare : o.exactMatch ? '=' : '') + v : '' )
84
+ .trigger( notrigger ? '' : 'search', searchType ).end()
85
+ .find('.number').val(v);
86
+ if ($cell.find('.number').length) {
87
+ $cell.find('.number')[0].disabled = (o.disabled || !chkd);
88
+ }
89
+ // update sticky header cell
90
+ if ($shcell.length) {
91
+ $shcell.find('.number').val(v)[0].disabled = (o.disabled || !chkd);
92
+ $shcell.find(compareSelect).val(compare);
93
+ if (o.addToggle) {
94
+ $shcell.find('.toggle')[0].checked = chkd;
95
+ }
96
+ }
97
+ };
98
+ $number.remove();
99
+
100
+ if (numberSupported) {
101
+ t = o.addToggle ? '<div class="button"><input id="html5button' + indx + '" type="checkbox" class="toggle" />' +
102
+ '<label for="html5button' + indx + '"></label></div>' : '';
103
+ t += '<input class="number" type="number" min="' + o.min + '" max="' + o.max + '" value="' +
104
+ o.value + '" step="' + o.step + '" />';
105
+ // add HTML5 number (spinner)
106
+ $cell
107
+ .append(t + '<input type="hidden" />')
108
+ .find('.toggle, .number').bind('change', function(){
109
+ updateNumber();
110
+ })
111
+ .closest('thead').find('th[data-column=' + indx + ']')
112
+ .addClass('filter-parsed') // get exact numbers from column
113
+ // on reset
114
+ .closest('table').bind('filterReset', function(){
115
+ if ($.isArray(o.compare)) {
116
+ $cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
117
+ }
118
+ // turn off the toggle checkbox
119
+ if (o.addToggle) {
120
+ $cell.find('.toggle')[0].checked = false;
121
+ if ($shcell.length) {
122
+ $shcell.find('.toggle')[0].checked = false;
123
+ }
124
+ }
125
+ $cell.find('.number').val( o.value );
126
+ setTimeout(function(){
127
+ updateNumber();
128
+ }, 0);
129
+ });
130
+ $input = $cell.find('input[type=hidden]').bind('change', function(){
131
+ $cell.find('.number').val( this.value );
132
+ updateNumber();
133
+ });
134
+
135
+ // update slider from hidden input, in case of saved filters
136
+ c.$table.bind('filterFomatterUpdate', function(){
137
+ var val = tsff.updateCompare($cell, $input, o)[0] || o.value;
138
+ $cell.find('.number').val( ((val || '') + '').replace(/[><=]/g,'') );
139
+ updateNumber(false, true);
140
+ ts.filter.formatterUpdated($cell, indx);
141
+ });
142
+
143
+ if (o.compare) {
144
+ // add compare select
145
+ tsff.addCompare($cell, indx, o);
146
+ $cell.find(compareSelect).bind('change', function(){
147
+ updateNumber();
148
+ });
149
+ }
150
+
151
+ // has sticky headers?
152
+ c.$table.bind('stickyHeadersInit', function(){
153
+ $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
154
+ $shcell
155
+ .append(t)
156
+ .find('.toggle, .number').bind('change', function(){
157
+ $cell.find('.number').val( $(this).val() );
158
+ updateNumber();
159
+ });
160
+
161
+ if (o.compare) {
162
+ // add compare select
163
+ tsff.addCompare($shcell, indx, o);
164
+ $shcell.find(compareSelect).bind('change', function(){
165
+ $cell.find(compareSelect).val( $(this).val() );
166
+ updateNumber();
167
+ });
168
+ }
169
+
170
+ updateNumber();
171
+ });
172
+
173
+ updateNumber();
174
+
175
+ }
176
+
177
+ return numberSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
178
+ },
179
+
180
+ /**********************\
181
+ HTML5 range slider
182
+ \**********************/
183
+ html5Range : function($cell, indx, def5Range) {
184
+ var o = $.extend({
185
+ value : 0,
186
+ min : 0,
187
+ max : 100,
188
+ step : 1,
189
+ delayed : true,
190
+ valueToHeader : true,
191
+ exactMatch : true,
192
+ cellText : '',
193
+ compare : '',
194
+ allText : 'all',
195
+ skipTest : false
196
+ }, def5Range),
197
+
198
+ $input,
199
+ // test browser for HTML5 range support
200
+ $range = $('<input type="range" style="visibility:hidden;" value="test">').appendTo($cell),
201
+ // test if HTML5 range is supported - from Modernizr (but I left out the method to detect in Safari 2-4)
202
+ // see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/inputtypes.js
203
+ rangeSupported = o.skipTest || $range.attr('type') === 'range' && $range.val() !== 'test',
204
+ $shcell = [],
205
+ c = $cell.closest('table')[0].config,
206
+
207
+ updateRange = function(v, delayed, notrigger){
208
+ /*jshint eqeqeq:false */
209
+ // hidden input changes may include compare symbols
210
+ v = ( typeof v === "undefined" ? $input.val() : v ).toString().replace(/[<>=]/g,'') || o.value;
211
+ var compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
212
+ t = ' (' + (compare ? compare + v : v == o.min ? o.allText : v) + ')',
213
+ searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
214
+ $cell.find('input[type=hidden]')
215
+ // add equal to the beginning, so we filter exact numbers
216
+ .val( ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) ) )
217
+ //( val == o.min ? '' : val + (o.exactMatch ? '=' : ''))
218
+ .trigger( notrigger ? '' : 'search', searchType ).end()
219
+ .find('.range').val(v);
220
+ // or add current value to the header cell, if desired
221
+ $cell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
222
+ // update sticky header cell
223
+ if ($shcell.length) {
224
+ $shcell
225
+ .find('.range').val(v).end()
226
+ .find(compareSelect).val( compare );
227
+ $shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
228
+ }
229
+ };
230
+ $range.remove();
231
+
232
+ if (rangeSupported) {
233
+ // add HTML5 range
234
+ $cell
235
+ .html('<input type="hidden"><input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
236
+ .closest('thead').find('th[data-column=' + indx + ']')
237
+ .addClass('filter-parsed') // get exact numbers from column
238
+ // add span to header for the current slider value
239
+ .find('.tablesorter-header-inner').append('<span class="curvalue" />');
240
+ // hidden filter update namespace trigger by filter widget
241
+ $input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
242
+ /*jshint eqeqeq:false */
243
+ var v = this.value,
244
+ compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '';
245
+ if (v !== this.lastValue) {
246
+ this.lastValue = ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) );
247
+ this.value = this.lastValue;
248
+ updateRange( v );
249
+ }
250
+ });
251
+
252
+ $cell.find('.range').bind('change', function(){
253
+ updateRange( this.value );
254
+ });
255
+
256
+ // update spinner from hidden input, in case of saved filters
257
+ c.$table.bind('filterFomatterUpdate', function(){
258
+ var val = tsff.updateCompare($cell, $input, o)[0];
259
+ $cell.find('.range').val( val );
260
+ updateRange(val, false, true);
261
+ ts.filter.formatterUpdated($cell, indx);
262
+ });
263
+
264
+ if (o.compare) {
265
+ // add compare select
266
+ tsff.addCompare($cell, indx, o);
267
+ $cell.find(compareSelect).bind('change', function(){
268
+ updateRange();
269
+ });
270
+ }
271
+
272
+ // has sticky headers?
273
+ c.$table.bind('stickyHeadersInit', function(){
274
+ $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
275
+ $shcell
276
+ .html('<input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
277
+ .find('.range').bind('change', function(){
278
+ updateRange( $shcell.find('.range').val() );
279
+ });
280
+ updateRange();
281
+
282
+ if (o.compare) {
283
+ // add compare select
284
+ tsff.addCompare($shcell, indx, o);
285
+ $shcell.find(compareSelect).bind('change', function(){
286
+ $cell.find(compareSelect).val( $(this).val() );
287
+ updateRange();
288
+ });
289
+ }
290
+
291
+ });
292
+
293
+ // on reset
294
+ $cell.closest('table').bind('filterReset', function(){
295
+ if ($.isArray(o.compare)) {
296
+ $cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
297
+ }
298
+ setTimeout(function(){
299
+ updateRange(o.value, false, true);
300
+ }, 0);
301
+ });
302
+ updateRange();
303
+
304
+ }
305
+
306
+ return rangeSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
307
+ },
308
+
309
+ /**********************\
310
+ HTML5 Color picker
311
+ \**********************/
312
+ html5Color: function($cell, indx, defColor) {
313
+ var t, o = $.extend({
314
+ value : '#000000',
315
+ disabled : false,
316
+ addToggle : true,
317
+ exactMatch : true,
318
+ valueToHeader : false,
319
+ skipTest : false
320
+ }, defColor),
321
+ $input,
322
+ // Add a hidden input to hold the range values
323
+ $color = $('<input type="color" style="visibility:hidden;" value="test">').appendTo($cell),
324
+ // test if HTML5 color is supported - from Modernizr
325
+ colorSupported = o.skipTest || $color.attr('type') === 'color' && $color.val() !== 'test',
326
+ $shcell = [],
327
+ c = $cell.closest('table')[0].config,
328
+
329
+ updateColor = function(v, notrigger){
330
+ v = ( typeof v === "undefined" ? $input.val() : v ).toString().replace('=','') || o.value;
331
+ var chkd = true,
332
+ t = ' (' + v + ')';
333
+ if (o.addToggle) {
334
+ chkd = $cell.find('.toggle').is(':checked');
335
+ }
336
+ if ($cell.find('.colorpicker').length) {
337
+ $cell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
338
+ }
339
+
340
+ $input
341
+ .val( chkd ? v + (o.exactMatch ? '=' : '') : '' )
342
+ .trigger( !c.$table[0].hasInitialized || notrigger ? '' : 'search' );
343
+ if (o.valueToHeader) {
344
+ // add current color to the header cell
345
+ $cell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
346
+ } else {
347
+ // current color to span in cell
348
+ $cell.find('.currentColor').html(t);
349
+ }
350
+
351
+ // update sticky header cell
352
+ if ($shcell.length) {
353
+ $shcell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
354
+ if (o.addToggle) {
355
+ $shcell.find('.toggle')[0].checked = chkd;
356
+ }
357
+ if (o.valueToHeader) {
358
+ // add current color to the header cell
359
+ $shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
360
+ } else {
361
+ // current color to span in cell
362
+ $shcell.find('.currentColor').html(t);
363
+ }
364
+ }
365
+ };
366
+ $color.remove();
367
+
368
+ if (colorSupported) {
369
+ t = '' + indx + Math.round(Math.random() * 100);
370
+ // add HTML5 color picker
371
+ t = '<div class="color-controls-wrapper">' +
372
+ (o.addToggle ? '<div class="button"><input id="colorbutton' + t + '" type="checkbox" class="toggle" /><label for="colorbutton' +
373
+ t + '"></label></div>' : '') +
374
+ '<input type="hidden"><input class="colorpicker" type="color" />' +
375
+ (o.valueToHeader ? '' : '<span class="currentColor">(#000000)</span>') + '</div>';
376
+ $cell.html(t);
377
+ // add span to header for the current color value - only works if the line in the updateColor() function is also un-commented out
378
+ if (o.valueToHeader) {
379
+ $cell.closest('thead').find('th[data-column=' + indx + ']').find('.tablesorter-header-inner').append('<span class="curcolor" />');
380
+ }
381
+
382
+ $cell.find('.toggle, .colorpicker').bind('change', function(){
383
+ updateColor( $cell.find('.colorpicker').val() );
384
+ });
385
+
386
+ // hidden filter update namespace trigger by filter widget
387
+ $input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
388
+ updateColor( this.value );
389
+ });
390
+
391
+ // update slider from hidden input, in case of saved filters
392
+ c.$table.bind('filterFomatterUpdate', function(){
393
+ updateColor( $input.val(), true );
394
+ ts.filter.formatterUpdated($cell, indx);
395
+ });
396
+
397
+ // on reset
398
+ $cell.closest('table').bind('filterReset', function(){
399
+ // just turn off the colorpicker
400
+ if (o.addToggle) {
401
+ $cell.find('.toggle')[0].checked = false;
402
+ }
403
+ // delay needed because default color needs to be set in the filter
404
+ // there is no compare option here, so if addToggle = false,
405
+ // default color is #000000 (even with no value set)
406
+ setTimeout(function(){
407
+ updateColor();
408
+ }, 0);
409
+ });
410
+
411
+ // has sticky headers?
412
+ c.$table.bind('stickyHeadersInit', function(){
413
+ $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx);
414
+ $shcell
415
+ .html(t)
416
+ .find('.toggle, .colorpicker').bind('change', function(){
417
+ updateColor( $shcell.find('.colorpicker').val() );
418
+ });
419
+ updateColor( $shcell.find('.colorpicker').val() );
420
+ });
421
+
422
+ updateColor( o.value );
423
+ }
424
+ return colorSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
425
+ }
426
+
427
+ };
428
+
429
+ })(jQuery);