jquery-tablesorter 1.18.1 → 1.18.2
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.
- checksums.yaml +4 -4
- data/README.md +3 -4
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +218 -155
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +79 -43
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +139 -112
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +6 -4
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +138 -111
- metadata +2 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Widget: columnSelector (responsive table widget) - updated 8/
|
1
|
+
/* Widget: columnSelector (responsive table widget) - updated 8/23/2015 (v2.23.2) *//*
|
2
2
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
3
|
* by Justin Hallett & Rob Garrison
|
4
4
|
*/
|
@@ -224,7 +224,7 @@
|
|
224
224
|
}
|
225
225
|
// trigger columnUpdate if auto is true (it gets skipped in updateCols()
|
226
226
|
if (colSel.auto) {
|
227
|
-
c.$table.trigger(
|
227
|
+
c.$table.trigger(wo.columnSelector_updated);
|
228
228
|
}
|
229
229
|
},
|
230
230
|
|
@@ -299,7 +299,7 @@
|
|
299
299
|
if (wo.columnSelector_saveColumns && ts.storage) {
|
300
300
|
ts.storage( c.$table[0], 'tablesorter-columnSelector', colSel.states );
|
301
301
|
}
|
302
|
-
c.$table.trigger(
|
302
|
+
c.$table.trigger(wo.columnSelector_updated);
|
303
303
|
},
|
304
304
|
|
305
305
|
attachTo : function(table, elm) {
|
@@ -370,7 +370,9 @@
|
|
370
370
|
columnSelector_priority : 'data-priority',
|
371
371
|
// class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
|
372
372
|
// applied icons; use this class name (input.checked) instead of input:checked
|
373
|
-
columnSelector_cssChecked : 'checked'
|
373
|
+
columnSelector_cssChecked : 'checked',
|
374
|
+
// event triggered when columnSelector completes
|
375
|
+
columnSelector_updated : 'columnUpdate'
|
374
376
|
|
375
377
|
},
|
376
378
|
init: function(table, thisWidget, c, wo) {
|
@@ -1,11 +1,12 @@
|
|
1
|
-
/*! Widget: filter - updated 8/
|
1
|
+
/*! Widget: filter - updated 8/23/2015 (v2.23.2) *//*
|
2
2
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
3
|
* by Rob Garrison
|
4
4
|
*/
|
5
5
|
;( function ( $ ) {
|
6
6
|
'use strict';
|
7
|
-
var
|
8
|
-
|
7
|
+
var tsf,
|
8
|
+
ts = $.tablesorter || {},
|
9
|
+
tscss = ts.css;
|
9
10
|
|
10
11
|
$.extend( tscss, {
|
11
12
|
filterRow : 'tablesorter-filter-row',
|
@@ -49,7 +50,7 @@
|
|
49
50
|
},
|
50
51
|
format: function( table, c, wo ) {
|
51
52
|
if ( !c.$table.hasClass( 'hasFilters' ) ) {
|
52
|
-
|
53
|
+
tsf.init( table, c, wo );
|
53
54
|
}
|
54
55
|
},
|
55
56
|
remove: function( table, c, wo, refreshing ) {
|
@@ -61,7 +62,7 @@
|
|
61
62
|
$table
|
62
63
|
.removeClass( 'hasFilters' )
|
63
64
|
// add .tsfilter namespace to all BUT search
|
64
|
-
.unbind( events.replace(
|
65
|
+
.unbind( events.replace( ts.regex.spaces, ' ' ) )
|
65
66
|
// remove the filter row even if refreshing, because the column might have been moved
|
66
67
|
.find( '.' + tscss.filterRow ).remove();
|
67
68
|
if ( refreshing ) { return; }
|
@@ -76,7 +77,7 @@
|
|
76
77
|
}
|
77
78
|
});
|
78
79
|
|
79
|
-
ts.filter = {
|
80
|
+
tsf = ts.filter = {
|
80
81
|
|
81
82
|
// regex used in filter 'check' functions - not for general use and not documented
|
82
83
|
regex: {
|
@@ -85,9 +86,13 @@
|
|
85
86
|
filtered : /filtered/, // filtered (hidden) row class name; updated in the script
|
86
87
|
type : /undefined|number/, // check type
|
87
88
|
exact : /(^[\"\'=]+)|([\"\'=]+$)/g, // exact match (allow '==')
|
88
|
-
nondigit : /[^\w,. \-()]/g, // replace non-digits (from digit & currency parser)
|
89
89
|
operators : /[<>=]/g, // replace operators
|
90
|
-
query : '(q|query)' // replace filter queries
|
90
|
+
query : '(q|query)', // replace filter queries
|
91
|
+
wild01 : /\?/g, // wild card match 0 or 1
|
92
|
+
wild0More : /\*/g, // wild care match 0 or more
|
93
|
+
quote : /\"/g,
|
94
|
+
isNeg1 : /(>=?\s*-\d)/,
|
95
|
+
isNeg2 : /(<=?\s*\d)/
|
91
96
|
},
|
92
97
|
// function( c, data ) { }
|
93
98
|
// c = table.config
|
@@ -104,27 +109,27 @@
|
|
104
109
|
// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
|
105
110
|
types: {
|
106
111
|
or : function( c, data, vars ) {
|
107
|
-
if (
|
112
|
+
if ( tsf.regex.orTest.test( data.iFilter ) || tsf.regex.orSplit.test( data.filter ) ) {
|
108
113
|
var indx, filterMatched, query, regex,
|
109
114
|
// duplicate data but split filter
|
110
115
|
data2 = $.extend( {}, data ),
|
111
116
|
index = data.index,
|
112
117
|
parsed = data.parsed[ index ],
|
113
|
-
filter = data.filter.split(
|
114
|
-
iFilter = data.iFilter.split(
|
118
|
+
filter = data.filter.split( tsf.regex.orSplit ),
|
119
|
+
iFilter = data.iFilter.split( tsf.regex.orSplit ),
|
115
120
|
len = filter.length;
|
116
121
|
for ( indx = 0; indx < len; indx++ ) {
|
117
122
|
data2.nestedFilters = true;
|
118
|
-
data2.filter = '' + (
|
119
|
-
data2.iFilter = '' + (
|
120
|
-
query = '(' + (
|
123
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], index, parsed ) || '' );
|
124
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
|
125
|
+
query = '(' + ( tsf.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')';
|
121
126
|
try {
|
122
127
|
// use try/catch, because query may not be a valid regex if "|" is contained within a partial regex search,
|
123
128
|
// e.g "/(Alex|Aar" -> Uncaught SyntaxError: Invalid regular expression: /(/(Alex)/: Unterminated group
|
124
129
|
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
125
130
|
// filterMatched = data2.filter === '' && indx > 0 ? true
|
126
131
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
127
|
-
filterMatched = regex.test( data2.exact ) ||
|
132
|
+
filterMatched = regex.test( data2.exact ) || tsf.processTypes( c, data2, vars );
|
128
133
|
if ( filterMatched ) {
|
129
134
|
return filterMatched;
|
130
135
|
}
|
@@ -139,27 +144,27 @@
|
|
139
144
|
},
|
140
145
|
// Look for an AND or && operator ( logical and )
|
141
146
|
and : function( c, data, vars ) {
|
142
|
-
if (
|
147
|
+
if ( tsf.regex.andTest.test( data.filter ) ) {
|
143
148
|
var indx, filterMatched, result, query, regex,
|
144
149
|
// duplicate data but split filter
|
145
150
|
data2 = $.extend( {}, data ),
|
146
151
|
index = data.index,
|
147
152
|
parsed = data.parsed[ index ],
|
148
|
-
filter = data.filter.split(
|
149
|
-
iFilter = data.iFilter.split(
|
153
|
+
filter = data.filter.split( tsf.regex.andSplit ),
|
154
|
+
iFilter = data.iFilter.split( tsf.regex.andSplit ),
|
150
155
|
len = filter.length;
|
151
156
|
for ( indx = 0; indx < len; indx++ ) {
|
152
157
|
data2.nestedFilters = true;
|
153
|
-
data2.filter = '' + (
|
154
|
-
data2.iFilter = '' + (
|
155
|
-
query = ( '(' + (
|
158
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], index, parsed ) || '' );
|
159
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
|
160
|
+
query = ( '(' + ( tsf.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')' )
|
156
161
|
// replace wild cards since /(a*)/i will match anything
|
157
|
-
.replace(
|
162
|
+
.replace( tsf.regex.wild01, '\\S{1}' ).replace( tsf.regex.wild0More, '\\S*' );
|
158
163
|
try {
|
159
164
|
// use try/catch just in case RegExp is invalid
|
160
165
|
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
161
166
|
// look for an exact match with the 'and' unless the 'filter-match' class is found
|
162
|
-
result = ( regex.test( data2.exact ) ||
|
167
|
+
result = ( regex.test( data2.exact ) || tsf.processTypes( c, data2, vars ) );
|
163
168
|
if ( indx === 0 ) {
|
164
169
|
filterMatched = result;
|
165
170
|
} else {
|
@@ -176,10 +181,10 @@
|
|
176
181
|
},
|
177
182
|
// Look for regex
|
178
183
|
regex: function( c, data ) {
|
179
|
-
if (
|
184
|
+
if ( tsf.regex.regex.test( data.filter ) ) {
|
180
185
|
var matches,
|
181
186
|
// cache regex per column for optimal speed
|
182
|
-
regex = data.filter_regexCache[ data.index ] ||
|
187
|
+
regex = data.filter_regexCache[ data.index ] || tsf.regex.regex.exec( data.filter ),
|
183
188
|
isRegex = regex instanceof RegExp;
|
184
189
|
try {
|
185
190
|
if ( !isRegex ) {
|
@@ -198,18 +203,18 @@
|
|
198
203
|
// Look for operators >, >=, < or <=
|
199
204
|
operators: function( c, data ) {
|
200
205
|
// ignore empty strings... because '' < 10 is true
|
201
|
-
if (
|
206
|
+
if ( tsf.regex.operTest.test( data.iFilter ) && data.iExact !== '' ) {
|
202
207
|
var cachedValue, result, txt,
|
203
208
|
table = c.table,
|
204
209
|
index = data.index,
|
205
210
|
parsed = data.parsed[index],
|
206
|
-
query = ts.formatFloat( data.iFilter.replace(
|
211
|
+
query = ts.formatFloat( data.iFilter.replace( tsf.regex.operators, '' ), table ),
|
207
212
|
parser = c.parsers[index],
|
208
213
|
savedSearch = query;
|
209
214
|
// parse filter value in case we're comparing numbers ( dates )
|
210
215
|
if ( parsed || parser.type === 'numeric' ) {
|
211
|
-
txt = $.trim( '' + data.iFilter.replace(
|
212
|
-
result =
|
216
|
+
txt = $.trim( '' + data.iFilter.replace( tsf.regex.operators, '' ) );
|
217
|
+
result = tsf.parseFilter( c, txt, index, true );
|
213
218
|
query = ( typeof result === 'number' && result !== '' && !isNaN( result ) ) ? result : query;
|
214
219
|
}
|
215
220
|
// iExact may be numeric - see issue #149;
|
@@ -218,13 +223,13 @@
|
|
218
223
|
typeof data.cache !== 'undefined' ) {
|
219
224
|
cachedValue = data.cache;
|
220
225
|
} else {
|
221
|
-
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.
|
226
|
+
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
|
222
227
|
cachedValue = ts.formatFloat( txt, table );
|
223
228
|
}
|
224
|
-
if (
|
225
|
-
result =
|
226
|
-
} else if (
|
227
|
-
result =
|
229
|
+
if ( tsf.regex.gtTest.test( data.iFilter ) ) {
|
230
|
+
result = tsf.regex.gteTest.test( data.iFilter ) ? cachedValue >= query : cachedValue > query;
|
231
|
+
} else if ( tsf.regex.ltTest.test( data.iFilter ) ) {
|
232
|
+
result = tsf.regex.lteTest.test( data.iFilter ) ? cachedValue <= query : cachedValue < query;
|
228
233
|
}
|
229
234
|
// keep showing all rows if nothing follows the operator
|
230
235
|
if ( !result && savedSearch === '' ) {
|
@@ -236,13 +241,13 @@
|
|
236
241
|
},
|
237
242
|
// Look for a not match
|
238
243
|
notMatch: function( c, data ) {
|
239
|
-
if (
|
244
|
+
if ( tsf.regex.notTest.test( data.iFilter ) ) {
|
240
245
|
var indx,
|
241
246
|
txt = data.iFilter.replace( '!', '' ),
|
242
|
-
filter =
|
243
|
-
if (
|
247
|
+
filter = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
248
|
+
if ( tsf.regex.exact.test( filter ) ) {
|
244
249
|
// look for exact not matches - see #628
|
245
|
-
filter = filter.replace(
|
250
|
+
filter = filter.replace( tsf.regex.exact, '' );
|
246
251
|
return filter === '' ? true : $.trim( filter ) !== data.iExact;
|
247
252
|
} else {
|
248
253
|
indx = data.iExact.search( $.trim( filter ) );
|
@@ -254,27 +259,27 @@
|
|
254
259
|
// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
|
255
260
|
exact: function( c, data ) {
|
256
261
|
/*jshint eqeqeq:false */
|
257
|
-
if (
|
258
|
-
var txt = data.iFilter.replace(
|
259
|
-
filter =
|
262
|
+
if ( tsf.regex.exact.test( data.iFilter ) ) {
|
263
|
+
var txt = data.iFilter.replace( tsf.regex.exact, '' ),
|
264
|
+
filter = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
260
265
|
return data.anyMatch ? $.inArray( filter, data.rowArray ) >= 0 : filter == data.iExact;
|
261
266
|
}
|
262
267
|
return null;
|
263
268
|
},
|
264
269
|
// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
|
265
270
|
range : function( c, data ) {
|
266
|
-
if (
|
271
|
+
if ( tsf.regex.toTest.test( data.iFilter ) ) {
|
267
272
|
var result, tmp, range1, range2,
|
268
273
|
table = c.table,
|
269
274
|
index = data.index,
|
270
275
|
parsed = data.parsed[index],
|
271
276
|
// make sure the dash is for a range and not indicating a negative number
|
272
|
-
query = data.iFilter.split(
|
277
|
+
query = data.iFilter.split( tsf.regex.toSplit );
|
273
278
|
|
274
|
-
tmp = query[0].replace( ts.
|
275
|
-
range1 = ts.formatFloat(
|
276
|
-
tmp = query[1].replace( ts.
|
277
|
-
range2 = ts.formatFloat(
|
279
|
+
tmp = query[0].replace( ts.regex.nondigit, '' ) || '';
|
280
|
+
range1 = ts.formatFloat( tsf.parseFilter( c, tmp, index, parsed ), table );
|
281
|
+
tmp = query[1].replace( ts.regex.nondigit, '' ) || '';
|
282
|
+
range2 = ts.formatFloat( tsf.parseFilter( c, tmp, index, parsed ), table );
|
278
283
|
// parse filter value in case we're comparing numbers ( dates )
|
279
284
|
if ( parsed || c.parsers[index].type === 'numeric' ) {
|
280
285
|
result = c.parsers[ index ].format( '' + query[0], table, c.$headers.eq( index ), index );
|
@@ -285,7 +290,7 @@
|
|
285
290
|
if ( ( parsed || c.parsers[ index ].type === 'numeric' ) && !isNaN( range1 ) && !isNaN( range2 ) ) {
|
286
291
|
result = data.cache;
|
287
292
|
} else {
|
288
|
-
tmp = isNaN( data.iExact ) ? data.iExact.replace( ts.
|
293
|
+
tmp = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
|
289
294
|
result = ts.formatFloat( tmp, table );
|
290
295
|
}
|
291
296
|
if ( range1 > range2 ) {
|
@@ -297,18 +302,18 @@
|
|
297
302
|
},
|
298
303
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
299
304
|
wild : function( c, data ) {
|
300
|
-
if (
|
305
|
+
if ( tsf.regex.wildOrTest.test( data.iFilter ) ) {
|
301
306
|
var index = data.index,
|
302
307
|
parsed = data.parsed[ index ],
|
303
|
-
query = '' + (
|
308
|
+
query = '' + ( tsf.parseFilter( c, data.iFilter, index, parsed ) || '' );
|
304
309
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
305
|
-
if (
|
310
|
+
if ( !tsf.regex.wildTest.test( query ) && data.nestedFilters ) {
|
306
311
|
query = data.isMatch ? query : '^(' + query + ')$';
|
307
312
|
}
|
308
313
|
// parsing the filter may not work properly when using wildcards =/
|
309
314
|
try {
|
310
315
|
return new RegExp(
|
311
|
-
query.replace(
|
316
|
+
query.replace( tsf.regex.wild01, '\\S{1}' ).replace( tsf.regex.wild0More, '\\S*' ),
|
312
317
|
c.widgetOptions.filter_ignoreCase ? 'i' : ''
|
313
318
|
)
|
314
319
|
.test( data.exact );
|
@@ -320,12 +325,12 @@
|
|
320
325
|
},
|
321
326
|
// fuzzy text search; modified from https://github.com/mattyork/fuzzy ( MIT license )
|
322
327
|
fuzzy: function( c, data ) {
|
323
|
-
if (
|
328
|
+
if ( tsf.regex.fuzzyTest.test( data.iFilter ) ) {
|
324
329
|
var indx,
|
325
330
|
patternIndx = 0,
|
326
331
|
len = data.iExact.length,
|
327
332
|
txt = data.iFilter.slice( 1 ),
|
328
|
-
pattern =
|
333
|
+
pattern = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
329
334
|
for ( indx = 0; indx < len; indx++ ) {
|
330
335
|
if ( data.iExact[ indx ] === pattern[ patternIndx ] ) {
|
331
336
|
patternIndx += 1;
|
@@ -348,7 +353,7 @@
|
|
348
353
|
}, ts.language );
|
349
354
|
|
350
355
|
var options, string, txt, $header, column, filters, val, fxn, noSelect,
|
351
|
-
regex =
|
356
|
+
regex = tsf.regex;
|
352
357
|
c.$table.addClass( 'hasFilters' );
|
353
358
|
|
354
359
|
// define timers so using clearTimeout won't cause an undefined error
|
@@ -359,7 +364,7 @@
|
|
359
364
|
wo.filter_anyColumnSelector = '[data-column="all"],[data-column="any"]';
|
360
365
|
wo.filter_multipleColumnSelector = '[data-column*="-"],[data-column*=","]';
|
361
366
|
|
362
|
-
val = '\\{' +
|
367
|
+
val = '\\{' + tsf.regex.query + '\\}';
|
363
368
|
$.extend( regex, {
|
364
369
|
child : new RegExp( c.cssChildRow ),
|
365
370
|
filtered : new RegExp( wo.filter_filteredRow ),
|
@@ -368,9 +373,20 @@
|
|
368
373
|
toSplit : new RegExp( '(?:\\s+(?:-|' + ts.language.to + ')\\s+)', 'gi' ),
|
369
374
|
andTest : new RegExp( '\\s+(' + ts.language.and + '|&&)\\s+', 'i' ),
|
370
375
|
andSplit : new RegExp( '(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi' ),
|
376
|
+
orTest : /\|/,
|
371
377
|
orSplit : new RegExp( '(?:\\s+(?:' + ts.language.or + ')\\s+|\\|)', 'gi' ),
|
372
378
|
iQuery : new RegExp( val, 'i' ),
|
373
|
-
igQuery : new RegExp( val, 'ig' )
|
379
|
+
igQuery : new RegExp( val, 'ig' ),
|
380
|
+
operTest : /^[<>]=?/,
|
381
|
+
gtTest : />/,
|
382
|
+
gteTest : />=/,
|
383
|
+
ltTest : /</,
|
384
|
+
lteTest : /<=/,
|
385
|
+
notTest : /^\!/,
|
386
|
+
wildOrTest : /[\?\*\|]/,
|
387
|
+
wildTest : /\?\*/,
|
388
|
+
fuzzyTest : /^~/,
|
389
|
+
exactTest : /[=\"\|!]/
|
374
390
|
});
|
375
391
|
|
376
392
|
// don't build filter row if columnFilters is false or all columns are set to 'filter-false'
|
@@ -378,7 +394,7 @@
|
|
378
394
|
val = c.$headers.filter( '.filter-false, .parser-false' ).length;
|
379
395
|
if ( wo.filter_columnFilters !== false && val !== c.$headers.length ) {
|
380
396
|
// build filter row
|
381
|
-
|
397
|
+
tsf.buildRow( table, c, wo );
|
382
398
|
}
|
383
399
|
|
384
400
|
txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
|
@@ -391,13 +407,13 @@
|
|
391
407
|
c.$table.find( '.' + tscss.filterRow ).toggleClass( wo.filter_filteredRow, val ); // fixes #450
|
392
408
|
if ( !/(search|filter)/.test( event.type ) ) {
|
393
409
|
event.stopPropagation();
|
394
|
-
|
410
|
+
tsf.buildDefault( table, true );
|
395
411
|
}
|
396
412
|
if ( event.type === 'filterReset' ) {
|
397
413
|
c.$table.find( '.' + tscss.filter ).add( wo.filter_$externalFilters ).val( '' );
|
398
|
-
|
414
|
+
tsf.searching( table, [] );
|
399
415
|
} else if ( event.type === 'filterEnd' ) {
|
400
|
-
|
416
|
+
tsf.buildDefault( table, true );
|
401
417
|
} else {
|
402
418
|
// send false argument to force a new search; otherwise if the filter hasn't changed,
|
403
419
|
// it will return
|
@@ -411,7 +427,7 @@
|
|
411
427
|
// pass true ( skipFirst ) to prevent the tablesorter.setFilters function from skipping the first
|
412
428
|
// input ensures all inputs are updated when a search is triggered on the table
|
413
429
|
// $( 'table' ).trigger( 'search', [...] );
|
414
|
-
|
430
|
+
tsf.searching( table, filter, true );
|
415
431
|
}
|
416
432
|
return false;
|
417
433
|
});
|
@@ -444,7 +460,7 @@
|
|
444
460
|
noSelect = !( $header.hasClass( 'filter-false' ) || $header.hasClass( 'parser-false' ) );
|
445
461
|
options = '';
|
446
462
|
if ( fxn === true && noSelect ) {
|
447
|
-
|
463
|
+
tsf.buildSelect( table, column );
|
448
464
|
} else if ( typeof fxn === 'object' && noSelect ) {
|
449
465
|
// add custom drop down list
|
450
466
|
for ( string in fxn ) {
|
@@ -477,7 +493,7 @@
|
|
477
493
|
fxn = $.isFunction( txt ) ? true : ts.getColumnData( table, txt, column );
|
478
494
|
if ( fxn ) {
|
479
495
|
// updating so the extra options are appended
|
480
|
-
|
496
|
+
tsf.buildSelect( c.table, column, '', true, $header.hasClass( wo.filter_onlyAvail ) );
|
481
497
|
}
|
482
498
|
}
|
483
499
|
}
|
@@ -485,22 +501,22 @@
|
|
485
501
|
}
|
486
502
|
// not really updating, but if the column has both the 'filter-select' class &
|
487
503
|
// filter_functions set to true, it would append the same options twice.
|
488
|
-
|
504
|
+
tsf.buildDefault( table, true );
|
489
505
|
|
490
|
-
|
506
|
+
tsf.bindSearch( table, c.$table.find( '.' + tscss.filter ), true );
|
491
507
|
if ( wo.filter_external ) {
|
492
|
-
|
508
|
+
tsf.bindSearch( table, wo.filter_external );
|
493
509
|
}
|
494
510
|
|
495
511
|
if ( wo.filter_hideFilters ) {
|
496
|
-
|
512
|
+
tsf.hideFilters( table, c );
|
497
513
|
}
|
498
514
|
|
499
515
|
// show processing icon
|
500
516
|
if ( c.showProcessing ) {
|
501
517
|
txt = 'filterStart filterEnd '.split( ' ' ).join( c.namespace + 'filter ' );
|
502
518
|
c.$table
|
503
|
-
.unbind( txt.replace(
|
519
|
+
.unbind( txt.replace( ts.regex.spaces, ' ' ) )
|
504
520
|
.bind( txt, function( event, columns ) {
|
505
521
|
// only add processing to certain columns to all columns
|
506
522
|
$header = ( columns ) ?
|
@@ -520,11 +536,11 @@
|
|
520
536
|
// add default values
|
521
537
|
txt = 'tablesorter-initialized pagerBeforeInitialized '.split( ' ' ).join( c.namespace + 'filter ' );
|
522
538
|
c.$table
|
523
|
-
.unbind( txt.replace(
|
539
|
+
.unbind( txt.replace( ts.regex.spaces, ' ' ) )
|
524
540
|
.bind( txt, function() {
|
525
541
|
// redefine 'wo' as it does not update properly inside this callback
|
526
542
|
var wo = this.config.widgetOptions;
|
527
|
-
filters =
|
543
|
+
filters = tsf.setDefaults( table, c, wo ) || [];
|
528
544
|
if ( filters.length ) {
|
529
545
|
// prevent delayInit from triggering a cache build if filters are empty
|
530
546
|
if ( !( c.delayInit && filters.join( '' ) === '' ) ) {
|
@@ -535,7 +551,7 @@
|
|
535
551
|
// trigger init after setTimeout to prevent multiple filterStart/End/Init triggers
|
536
552
|
setTimeout( function() {
|
537
553
|
if ( !wo.filter_initialized ) {
|
538
|
-
|
554
|
+
tsf.filterInitComplete( c );
|
539
555
|
}
|
540
556
|
}, 100 );
|
541
557
|
});
|
@@ -543,7 +559,7 @@
|
|
543
559
|
if ( c.pager && c.pager.initialized && !wo.filter_initialized ) {
|
544
560
|
c.$table.trigger( 'filterFomatterUpdate' );
|
545
561
|
setTimeout( function() {
|
546
|
-
|
562
|
+
tsf.filterInitComplete( c );
|
547
563
|
}, 100 );
|
548
564
|
}
|
549
565
|
},
|
@@ -564,7 +580,7 @@
|
|
564
580
|
completed = function() {
|
565
581
|
wo.filter_initialized = true;
|
566
582
|
c.$table.trigger( 'filterInit', c );
|
567
|
-
|
583
|
+
tsf.findRows( c.table, c.$table.data( 'lastSearch' ) || [] );
|
568
584
|
};
|
569
585
|
if ( $.isEmptyObject( wo.filter_formatter ) ) {
|
570
586
|
completed();
|
@@ -716,7 +732,7 @@
|
|
716
732
|
// use data attribute instead of jQuery data since the head is cloned without including
|
717
733
|
// the data/binding
|
718
734
|
.attr( 'data-lastSearchTime', new Date().getTime() )
|
719
|
-
.unbind( tmp.replace(
|
735
|
+
.unbind( tmp.replace( ts.regex.spaces, ' ' ) )
|
720
736
|
// include change for select - fixes #473
|
721
737
|
.bind( 'keyup' + namespace, function( event ) {
|
722
738
|
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
|
@@ -736,17 +752,18 @@
|
|
736
752
|
return;
|
737
753
|
}
|
738
754
|
// change event = no delay; last true flag tells getFilters to skip newest timed input
|
739
|
-
|
755
|
+
tsf.searching( table, true, true );
|
740
756
|
})
|
741
757
|
.bind( 'search change keypress '.split( ' ' ).join( namespace + ' ' ), function( event ) {
|
742
|
-
|
758
|
+
// don't get cached data, in case data-column changes dynamically
|
759
|
+
var column = parseInt( $( this ).attr( 'data-column' ), 10 );
|
743
760
|
// don't allow 'change' event to process if the input value is the same - fixes #685
|
744
761
|
if ( event.which === 13 || event.type === 'search' ||
|
745
762
|
event.type === 'change' && this.value !== c.lastSearch[column] ) {
|
746
763
|
event.preventDefault();
|
747
764
|
// init search with no delay
|
748
765
|
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
|
749
|
-
|
766
|
+
tsf.searching( table, false, true );
|
750
767
|
}
|
751
768
|
});
|
752
769
|
},
|
@@ -756,11 +773,11 @@
|
|
756
773
|
if ( typeof filter === 'undefined' || filter === true ) {
|
757
774
|
// delay filtering
|
758
775
|
wo.searchTimer = setTimeout( function() {
|
759
|
-
|
776
|
+
tsf.checkFilters( table, filter, skipFirst );
|
760
777
|
}, wo.filter_liveSearch ? wo.filter_searchDelay : 10 );
|
761
778
|
} else {
|
762
779
|
// skip delay
|
763
|
-
|
780
|
+
tsf.checkFilters( table, filter, skipFirst );
|
764
781
|
}
|
765
782
|
},
|
766
783
|
checkFilters: function( table, filter, skipFirst ) {
|
@@ -774,7 +791,7 @@
|
|
774
791
|
// update cache if delayInit set & pager has initialized ( after user initiates a search )
|
775
792
|
if ( c.delayInit && c.pager && c.pager.initialized ) {
|
776
793
|
c.$table.trigger( 'updateCache', [ function() {
|
777
|
-
|
794
|
+
tsf.checkFilters( table, false, skipFirst );
|
778
795
|
} ] );
|
779
796
|
}
|
780
797
|
return;
|
@@ -805,11 +822,11 @@
|
|
805
822
|
if ( c.showProcessing ) {
|
806
823
|
// give it time for the processing icon to kick in
|
807
824
|
setTimeout( function() {
|
808
|
-
|
825
|
+
tsf.findRows( table, filters, combinedFilters );
|
809
826
|
return false;
|
810
827
|
}, 30 );
|
811
828
|
} else {
|
812
|
-
|
829
|
+
tsf.findRows( table, filters, combinedFilters );
|
813
830
|
return false;
|
814
831
|
}
|
815
832
|
},
|
@@ -852,8 +869,8 @@
|
|
852
869
|
},
|
853
870
|
defaultFilter: function( filter, mask ) {
|
854
871
|
if ( filter === '' ) { return filter; }
|
855
|
-
var regex =
|
856
|
-
maskLen = mask.match(
|
872
|
+
var regex = tsf.regex.iQuery,
|
873
|
+
maskLen = mask.match( tsf.regex.igQuery ).length,
|
857
874
|
query = maskLen > 1 ? $.trim( filter ).split( /\s/ ) : [ $.trim( filter ) ],
|
858
875
|
len = query.length - 1,
|
859
876
|
indx = 0,
|
@@ -889,7 +906,10 @@
|
|
889
906
|
// & don't target 'all' column inputs if they don't exist
|
890
907
|
targets = wo.filter_initialized || !$input.filter( wo.filter_anyColumnSelector ).length,
|
891
908
|
columns = [],
|
892
|
-
val = $.trim(
|
909
|
+
val = $.trim( tsf.getLatestSearch( $input ).attr( 'data-column' ) || '' );
|
910
|
+
if ( !/[,-]/.test(val) && val.length === 1 ) {
|
911
|
+
return parseInt( val, 10 );
|
912
|
+
}
|
893
913
|
// process column range
|
894
914
|
if ( targets && /-/.test( val ) ) {
|
895
915
|
ranges = val.match( /(\d+)\s*-\s*(\d+)/g );
|
@@ -936,9 +956,9 @@
|
|
936
956
|
var ffxn,
|
937
957
|
filterMatched = null,
|
938
958
|
matches = null;
|
939
|
-
for ( ffxn in
|
959
|
+
for ( ffxn in tsf.types ) {
|
940
960
|
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
|
941
|
-
matches =
|
961
|
+
matches = tsf.types[ffxn]( c, data, vars );
|
942
962
|
if ( matches !== null ) {
|
943
963
|
filterMatched = matches;
|
944
964
|
}
|
@@ -947,16 +967,23 @@
|
|
947
967
|
return filterMatched;
|
948
968
|
},
|
949
969
|
processRow: function( c, data, vars ) {
|
950
|
-
var
|
970
|
+
var hasSelect, result, val, filterMatched,
|
951
971
|
fxn, ffxn, txt,
|
952
|
-
regex =
|
972
|
+
regex = tsf.regex,
|
953
973
|
wo = c.widgetOptions,
|
954
|
-
showRow = true
|
974
|
+
showRow = true,
|
975
|
+
|
976
|
+
// if wo.filter_$anyMatch data-column attribute is changed dynamically
|
977
|
+
// we don't want to do an "anyMatch" search on one column using data
|
978
|
+
// for the entire row - see #998
|
979
|
+
columnIndex = wo.filter_$anyMatch && wo.filter_$anyMatch.length ?
|
980
|
+
// look for multiple columns '1-3,4-6,8'
|
981
|
+
tsf.multipleColumns( c, wo.filter_$anyMatch ) :
|
982
|
+
[];
|
983
|
+
|
955
984
|
data.$cells = data.$row.children();
|
956
985
|
|
957
|
-
if ( data.anyMatchFlag ) {
|
958
|
-
// look for multiple columns '1-3,4-6,8'
|
959
|
-
columnIndex = ts.filter.multipleColumns( c, wo.filter_$anyMatch );
|
986
|
+
if ( data.anyMatchFlag && columnIndex.length > 1 ) {
|
960
987
|
data.anyMatch = true;
|
961
988
|
data.isMatch = true;
|
962
989
|
data.rowArray = data.$cells.map( function( i ) {
|
@@ -980,7 +1007,7 @@
|
|
980
1007
|
data.cache = data.cacheArray.slice( 0, -1 ).join( ' ' );
|
981
1008
|
|
982
1009
|
vars.excludeMatch = vars.noAnyMatch;
|
983
|
-
filterMatched =
|
1010
|
+
filterMatched = tsf.processTypes( c, data, vars );
|
984
1011
|
|
985
1012
|
if ( filterMatched !== null ) {
|
986
1013
|
showRow = filterMatched;
|
@@ -1041,7 +1068,7 @@
|
|
1041
1068
|
|
1042
1069
|
val = true;
|
1043
1070
|
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
1044
|
-
data.filter =
|
1071
|
+
data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
1045
1072
|
// val is used to indicate that a filter select is using a default filter;
|
1046
1073
|
// so we override the exact & partial matches
|
1047
1074
|
val = false;
|
@@ -1072,13 +1099,13 @@
|
|
1072
1099
|
if ( filterMatched === null ) {
|
1073
1100
|
// cycle through the different filters
|
1074
1101
|
// filters return a boolean or null if nothing matches
|
1075
|
-
filterMatched =
|
1102
|
+
filterMatched = tsf.processTypes( c, data, vars );
|
1076
1103
|
if ( filterMatched !== null ) {
|
1077
1104
|
result = filterMatched;
|
1078
1105
|
// Look for match, and add child row data for matching
|
1079
1106
|
} else {
|
1080
1107
|
txt = ( data.iExact + data.childRowText )
|
1081
|
-
.indexOf(
|
1108
|
+
.indexOf( tsf.parseFilter( c, data.iFilter, columnIndex, data.parsed[ columnIndex ] ) );
|
1082
1109
|
result = ( ( !wo.filter_startsWith && txt >= 0 ) || ( wo.filter_startsWith && txt === 0 ) );
|
1083
1110
|
}
|
1084
1111
|
} else {
|
@@ -1098,7 +1125,7 @@
|
|
1098
1125
|
isChild, childRow, lastSearch, showRow, time, val, indx,
|
1099
1126
|
notFiltered, searchFiltered, query, injected, res, id, txt,
|
1100
1127
|
storedFilters = $.extend( [], filters ),
|
1101
|
-
regex =
|
1128
|
+
regex = tsf.regex,
|
1102
1129
|
c = table.config,
|
1103
1130
|
wo = c.widgetOptions,
|
1104
1131
|
// data object passed to filters; anyMatch is a flag for the filters
|
@@ -1175,7 +1202,7 @@
|
|
1175
1202
|
data.anyMatchFlag = true;
|
1176
1203
|
data.anyMatchFilter = '' + (
|
1177
1204
|
filters[ c.columns ] ||
|
1178
|
-
wo.filter_$anyMatch &&
|
1205
|
+
wo.filter_$anyMatch && tsf.getLatestSearch( wo.filter_$anyMatch ).val() ||
|
1179
1206
|
''
|
1180
1207
|
);
|
1181
1208
|
if ( wo.filter_columnAnyMatch ) {
|
@@ -1217,10 +1244,10 @@
|
|
1217
1244
|
// if there is NOT a logical 'or', or range ( 'to' or '-' ) in the string
|
1218
1245
|
!regex.alreadyFiltered.test( val ) &&
|
1219
1246
|
// if we are not doing exact matches, using '|' ( logical or ) or not '!'
|
1220
|
-
|
1247
|
+
!regex.exactTest.test( val ) &&
|
1221
1248
|
// don't search only filtered if the value is negative
|
1222
1249
|
// ( '> -10' => '> -100' will ignore hidden rows )
|
1223
|
-
!(
|
1250
|
+
!( regex.isNeg1.test( val ) || regex.isNeg2.test( val ) ) &&
|
1224
1251
|
// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
|
1225
1252
|
!( val !== '' && c.$filters && c.$filters.eq( indx ).find( 'select' ).length &&
|
1226
1253
|
!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
|
@@ -1239,7 +1266,7 @@
|
|
1239
1266
|
data.anyMatchFilter = ts.replaceAccents( data.anyMatchFilter );
|
1240
1267
|
}
|
1241
1268
|
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultAnyFilter ) ) {
|
1242
|
-
data.anyMatchFilter =
|
1269
|
+
data.anyMatchFilter = tsf.defaultFilter( data.anyMatchFilter, vars.defaultAnyFilter );
|
1243
1270
|
// clear search filtered flag because default filters are not saved to the last search
|
1244
1271
|
searchFiltered = false;
|
1245
1272
|
}
|
@@ -1282,7 +1309,7 @@
|
|
1282
1309
|
'';
|
1283
1310
|
}
|
1284
1311
|
|
1285
|
-
showRow =
|
1312
|
+
showRow = tsf.processRow( c, data, vars );
|
1286
1313
|
childRow = rowData.$row.filter( ':gt( 0 )' );
|
1287
1314
|
|
1288
1315
|
if ( wo.filter_childRows && childRow.length ) {
|
@@ -1293,7 +1320,7 @@
|
|
1293
1320
|
data.cacheArray = rowData.child[ indx ];
|
1294
1321
|
data.rawArray = data.cacheArray;
|
1295
1322
|
// use OR comparison on child rows
|
1296
|
-
showRow = showRow ||
|
1323
|
+
showRow = showRow || tsf.processRow( c, data, vars );
|
1297
1324
|
}
|
1298
1325
|
}
|
1299
1326
|
childRow.toggleClass( wo.filter_filteredRow, !showRow );
|
@@ -1355,7 +1382,7 @@
|
|
1355
1382
|
}
|
1356
1383
|
if ( arry === false ) {
|
1357
1384
|
// fall back to original method
|
1358
|
-
arry =
|
1385
|
+
arry = tsf.getOptions( table, column, onlyAvail );
|
1359
1386
|
}
|
1360
1387
|
|
1361
1388
|
// get unique elements and sort the list
|
@@ -1467,13 +1494,13 @@
|
|
1467
1494
|
// nothing included in arry ( external source ), so get the options from
|
1468
1495
|
// filter_selectSource or column data
|
1469
1496
|
if ( typeof arry === 'undefined' || arry === '' ) {
|
1470
|
-
arry =
|
1497
|
+
arry = tsf.getOptionSource( table, column, onlyAvail );
|
1471
1498
|
}
|
1472
1499
|
|
1473
1500
|
if ( $.isArray( arry ) ) {
|
1474
1501
|
// build option list
|
1475
1502
|
for ( indx = 0; indx < arry.length; indx++ ) {
|
1476
|
-
txt = arry[indx] = ( '' + arry[indx] ).replace(
|
1503
|
+
txt = arry[indx] = ( '' + arry[indx] ).replace( tsf.regex.quote, '"' );
|
1477
1504
|
val = txt;
|
1478
1505
|
// allow including a symbol in the selectSource array
|
1479
1506
|
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
@@ -1529,7 +1556,7 @@
|
|
1529
1556
|
// look for the filter-select class; build/update it if found
|
1530
1557
|
if ( ( $header.hasClass( 'filter-select' ) ||
|
1531
1558
|
ts.getColumnData( table, wo.filter_functions, columnIndex ) === true ) && noSelect ) {
|
1532
|
-
|
1559
|
+
tsf.buildSelect( table, columnIndex, '', updating, $header.hasClass( wo.filter_onlyAvail ) );
|
1533
1560
|
}
|
1534
1561
|
}
|
1535
1562
|
}
|
@@ -1565,7 +1592,7 @@
|
|
1565
1592
|
$column = $filters.filter( cols );
|
1566
1593
|
if ( $column.length ) {
|
1567
1594
|
// move the latest search to the first slot in the array
|
1568
|
-
$column =
|
1595
|
+
$column = tsf.getLatestSearch( $column );
|
1569
1596
|
if ( $.isArray( setFilters ) ) {
|
1570
1597
|
// skip first ( latest input ) to maintain cursor position while typing
|
1571
1598
|
if ( skipFirst && $column.length > 1 ) {
|
@@ -1615,7 +1642,7 @@
|
|
1615
1642
|
// ensure new set filters are applied, even if the search is the same
|
1616
1643
|
c.lastCombinedFilter = null;
|
1617
1644
|
c.lastSearch = [];
|
1618
|
-
|
1645
|
+
tsf.searching( c.table, filter, skipFirst );
|
1619
1646
|
c.$table.trigger( 'filterFomatterUpdate' );
|
1620
1647
|
}
|
1621
1648
|
return !!valid;
|