jquery-tablesorter 1.14.1 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
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);