jquery-tablesorter 1.16.5 → 1.17.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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +38 -27
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +1104 -839
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +167 -123
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +938 -717
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date.js +5 -5
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-globalize.js +46 -0
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +96 -72
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-named-numbers.js +6 -5
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-network.js +26 -17
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columns.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +95 -42
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +921 -700
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +5 -3
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +22 -20
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +7 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +40 -29
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +6 -6
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-saveSort.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +53 -31
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-storage.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-uitheme.js +1 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.black-ice.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.blue.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap_2.css +8 -6
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.dark.css +2 -1
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.default.css +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf240445d0e97fd4ef728159289bc7db7b0865de
|
4
|
+
data.tar.gz: e7b1e3511ffd03b9e1da5c5877fa1428270bcac1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f26a5aaae4e5683e0e748a65516926a4bf24391c1bb81577aafd07a7f6fff6c7c41cb08d9ce3eb00885bd10365844b56fed5079db6e5c5c12edb0fa4c625dbf3
|
7
|
+
data.tar.gz: 67ef7bbd510a4d350516b1bf8f231bacab71006b0e248aedfb183dcb0a257115132f7ca6cc093203aa9c7bc75c105af5f86c2cfd19f2582c2b6cd75ebb23ca15
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
Simple integration of jquery-tablesorter into the asset pipeline.
|
6
6
|
|
7
|
-
Current tablesorter version: 2.
|
7
|
+
Current tablesorter version: 2.22.0 (5/17/2015), [documentation]
|
8
8
|
|
9
9
|
Any issue associated with the js/css files, please report to [Mottie's fork].
|
10
10
|
|
@@ -26,7 +26,7 @@ Or install it yourself as:
|
|
26
26
|
|
27
27
|
Rails 3.2 and higher (tested up to 4.2)
|
28
28
|
|
29
|
-
Tested with ruby 1.9.3 - 2.2.
|
29
|
+
Tested with ruby 1.9.3 - 2.2.2
|
30
30
|
|
31
31
|
## Usage
|
32
32
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
* tablesorter (FORK) pager plugin
|
3
|
-
* updated
|
3
|
+
* updated 5/17/2015 (v2.22.0)
|
4
4
|
*/
|
5
5
|
/*jshint browser:true, jquery:true, unused:false */
|
6
6
|
;(function($) {
|
@@ -377,12 +377,12 @@
|
|
377
377
|
// process data
|
378
378
|
if ( typeof(p.ajaxProcessing) === "function" ) {
|
379
379
|
// ajaxProcessing result: [ total, rows, headers ]
|
380
|
-
var i, j, hsh, $f, $sh,
|
380
|
+
var i, j, t, hsh, $f, $sh, $headers, $h, icon, th, d, l, rr_count, len,
|
381
381
|
c = table.config,
|
382
|
-
$
|
382
|
+
$table = c.$table,
|
383
383
|
tds = '',
|
384
384
|
result = p.ajaxProcessing(data, table, xhr) || [ 0, [] ],
|
385
|
-
hl = $
|
385
|
+
hl = $table.find('thead th').length;
|
386
386
|
|
387
387
|
// Clean up any previous error.
|
388
388
|
ts.showError(table);
|
@@ -445,28 +445,30 @@
|
|
445
445
|
p.processAjaxOnInit = true;
|
446
446
|
// only add new header text if the length matches
|
447
447
|
if ( th && th.length === hl ) {
|
448
|
-
hsh = $
|
448
|
+
hsh = $table.hasClass('hasStickyHeaders');
|
449
449
|
$sh = hsh ? c.widgetOptions.$sticky.children('thead:first').children('tr').children() : '';
|
450
|
-
$f = $
|
450
|
+
$f = $table.find('tfoot tr:first').children();
|
451
451
|
// don't change td headers (may contain pager)
|
452
|
-
c.$headers.filter('th')
|
453
|
-
|
452
|
+
$headers = c.$headers.filter( 'th ' );
|
453
|
+
len = $headers.length;
|
454
|
+
for ( j = 0; j < len; j++ ) {
|
455
|
+
$h = $headers.eq( j );
|
454
456
|
// add new test within the first span it finds, or just in the header
|
455
|
-
if ( $
|
456
|
-
|
457
|
-
$
|
457
|
+
if ( $h.find('.' + ts.css.icon).length ) {
|
458
|
+
icon = $h.find('.' + ts.css.icon).clone(true);
|
459
|
+
$h.find('.tablesorter-header-inner').html( th[j] ).append(icon);
|
458
460
|
if ( hsh && $sh.length ) {
|
459
|
-
|
460
|
-
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(
|
461
|
+
icon = $sh.eq(j).find('.' + ts.css.icon).clone(true);
|
462
|
+
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icon);
|
461
463
|
}
|
462
464
|
} else {
|
463
|
-
$
|
465
|
+
$h.find('.tablesorter-header-inner').html( th[j] );
|
464
466
|
if (hsh && $sh.length) {
|
465
467
|
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
|
466
468
|
}
|
467
469
|
}
|
468
470
|
$f.eq(j).html( th[j] );
|
469
|
-
}
|
471
|
+
}
|
470
472
|
}
|
471
473
|
}
|
472
474
|
if (c.showProcessing) {
|
@@ -479,7 +481,7 @@
|
|
479
481
|
p.last.currentFilters = p.currentFilters;
|
480
482
|
p.last.sortList = (c.sortList || []).join(',');
|
481
483
|
updatePageDisplay(table, p, false);
|
482
|
-
$
|
484
|
+
$table.trigger('updateCache', [function(){
|
483
485
|
if (p.initialized) {
|
484
486
|
// apply widgets after table has rendered & after a delay to prevent
|
485
487
|
// multiple applyWidget blocking code from blocking this trigger
|
@@ -487,7 +489,7 @@
|
|
487
489
|
if (c.debug) {
|
488
490
|
ts.log('Pager: Triggering pagerChange');
|
489
491
|
}
|
490
|
-
$
|
492
|
+
$table
|
491
493
|
.trigger('applyWidgets')
|
492
494
|
.trigger('pagerChange', p);
|
493
495
|
updatePageDisplay(table, p, true);
|
@@ -649,6 +651,7 @@
|
|
649
651
|
},
|
650
652
|
|
651
653
|
showAllRows = function(table, p){
|
654
|
+
var index, $controls, len;
|
652
655
|
if ( p.ajax ) {
|
653
656
|
pagerArrows(p, true);
|
654
657
|
} else {
|
@@ -669,9 +672,15 @@
|
|
669
672
|
}
|
670
673
|
}
|
671
674
|
// disable size selector
|
672
|
-
p.$size
|
673
|
-
|
674
|
-
|
675
|
+
$controls = p.$size
|
676
|
+
.add( p.$goto )
|
677
|
+
.add( p.$container.find( '.ts-startRow, .ts-page' ) );
|
678
|
+
len = $controls.length;
|
679
|
+
for ( index = 0; index < len; index++ ) {
|
680
|
+
$controls.eq( index )
|
681
|
+
.attr( 'aria-disabled', 'true' )
|
682
|
+
.addClass( p.cssDisabled )[0].disabled = true;
|
683
|
+
}
|
675
684
|
},
|
676
685
|
|
677
686
|
// updateCache if delayInit: true
|
@@ -1043,13 +1052,15 @@
|
|
1043
1052
|
}() });
|
1044
1053
|
|
1045
1054
|
// see #486
|
1046
|
-
ts.showError = function(table, message){
|
1047
|
-
$
|
1048
|
-
|
1049
|
-
|
1055
|
+
ts.showError = function(table, message) {
|
1056
|
+
var index, $row, c, errorRow,
|
1057
|
+
$table = $( table ),
|
1058
|
+
len = $table.length;
|
1059
|
+
for ( index = 0; index < len; index++ ) {
|
1060
|
+
c = $table[ index ].config;
|
1061
|
+
if ( c ) {
|
1050
1062
|
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
|
1051
|
-
|
1052
|
-
if (typeof message === 'undefined') {
|
1063
|
+
if ( typeof message === 'undefined' ) {
|
1053
1064
|
c.$table.find('thead').find(c.selectorRemove).remove();
|
1054
1065
|
} else {
|
1055
1066
|
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
|
@@ -1065,7 +1076,7 @@
|
|
1065
1076
|
});
|
1066
1077
|
}
|
1067
1078
|
}
|
1068
|
-
}
|
1079
|
+
}
|
1069
1080
|
};
|
1070
1081
|
|
1071
1082
|
// extend plugin scope
|
@@ -4,7 +4,7 @@
|
|
4
4
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀▀██
|
5
5
|
█████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
|
6
6
|
*/
|
7
|
-
/*! tablesorter (FORK) - updated
|
7
|
+
/*! tablesorter (FORK) - updated 05-17-2015 (v2.22.0)*/
|
8
8
|
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
|
9
9
|
(function(factory) {
|
10
10
|
if (typeof define === 'function' && define.amd) {
|
@@ -16,7 +16,7 @@
|
|
16
16
|
}
|
17
17
|
}(function($) {
|
18
18
|
|
19
|
-
/*! TableSorter (FORK) v2.
|
19
|
+
/*! TableSorter (FORK) v2.22.0 *//*
|
20
20
|
* Client-side table sorting with ease!
|
21
21
|
* @requires jQuery v1.2.6+
|
22
22
|
*
|
@@ -44,7 +44,7 @@
|
|
44
44
|
|
45
45
|
var ts = this;
|
46
46
|
|
47
|
-
ts.version = '2.
|
47
|
+
ts.version = '2.22.0';
|
48
48
|
|
49
49
|
ts.parsers = [];
|
50
50
|
ts.widgets = [];
|
@@ -119,6 +119,11 @@
|
|
119
119
|
cssNoSort : 'tablesorter-noSort', // class name added to element inside header; clicking on it won't cause a sort
|
120
120
|
cssIgnoreRow : 'tablesorter-ignoreRow', // header row to ignore; cells within this row will not be added to c.$headers
|
121
121
|
|
122
|
+
// *** events
|
123
|
+
pointerClick : 'click',
|
124
|
+
pointerDown : 'mousedown',
|
125
|
+
pointerUp : 'mouseup',
|
126
|
+
|
122
127
|
// *** selectors
|
123
128
|
selectorHeaders : '> thead th, > thead td',
|
124
129
|
selectorSort : 'th, td', // jQuery selector of content within selectorHeaders that is clickable to trigger a sort
|
@@ -203,7 +208,11 @@
|
|
203
208
|
$node = node.jquery ? node : $(node);
|
204
209
|
if (typeof(t) === 'string') {
|
205
210
|
// check data-attribute first when set to 'basic'; don't use node.innerText - it's really slow!
|
206
|
-
|
211
|
+
// http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/
|
212
|
+
return $.trim(
|
213
|
+
( t === 'basic' ? $node.attr(c.textAttribute) || node.textContent : node.textContent ) ||
|
214
|
+
$node.text()
|
215
|
+
);
|
207
216
|
} else {
|
208
217
|
if (typeof(t) === 'function') {
|
209
218
|
return $.trim( t($node[0], c.table, cellIndex) );
|
@@ -212,7 +221,7 @@
|
|
212
221
|
}
|
213
222
|
}
|
214
223
|
// fallback
|
215
|
-
return $.trim( $node[0].textContent || $node.text()
|
224
|
+
return $.trim( $node[0].textContent || $node.text() );
|
216
225
|
};
|
217
226
|
|
218
227
|
function detectParserForColumn(table, rows, rowIndex, cellIndex) {
|
@@ -246,6 +255,32 @@
|
|
246
255
|
return ts.getParserById('text');
|
247
256
|
}
|
248
257
|
|
258
|
+
// centralized function to extract/parse cell contents
|
259
|
+
function getParsedText( c, cell, colIndex, txt ) {
|
260
|
+
if ( typeof txt === 'undefined' ) {
|
261
|
+
txt = ts.getElementText( c, cell, colIndex );
|
262
|
+
}
|
263
|
+
// if no parser, make sure to return the txt
|
264
|
+
var val = '' + txt,
|
265
|
+
parser = c.parsers[ colIndex ],
|
266
|
+
extractor = c.extractors[ colIndex ];
|
267
|
+
if ( parser ) {
|
268
|
+
// do extract before parsing, if there is one
|
269
|
+
if ( extractor && typeof extractor.format === 'function' ) {
|
270
|
+
txt = extractor.format( txt, c.table, cell, colIndex );
|
271
|
+
}
|
272
|
+
// allow parsing if the string is empty, previously parsing would change it to zero,
|
273
|
+
// in case the parser needs to extract data from the table cell attributes
|
274
|
+
val = parser.id === 'no-parser' ? '' :
|
275
|
+
// make sure txt is a string (extractor may have converted it)
|
276
|
+
parser.format( '' + txt, c.table, cell, colIndex );
|
277
|
+
if ( c.ignoreCase && typeof val === 'string' ) {
|
278
|
+
val = val.toLowerCase();
|
279
|
+
}
|
280
|
+
}
|
281
|
+
return val;
|
282
|
+
}
|
283
|
+
|
249
284
|
function buildParserCache(table) {
|
250
285
|
var c = table.config,
|
251
286
|
// update table bodies in case we start with an empty table
|
@@ -309,11 +344,10 @@
|
|
309
344
|
|
310
345
|
/* utils */
|
311
346
|
function buildCache(table) {
|
312
|
-
var cc, t,
|
313
|
-
totalRows, rowData, colMax,
|
347
|
+
var cc, t, v, i, j, k, $row, cols, cacheTime,
|
348
|
+
totalRows, rowData, prevRowData, colMax,
|
314
349
|
c = table.config,
|
315
350
|
$tb = c.$tbodies,
|
316
|
-
extractors = c.extractors,
|
317
351
|
parsers = c.parsers;
|
318
352
|
c.cache = {};
|
319
353
|
c.totalRows = 0;
|
@@ -344,62 +378,61 @@
|
|
344
378
|
raw: [] // original row text
|
345
379
|
};
|
346
380
|
/** Add the table data to main data array */
|
347
|
-
$row = $($tb[k].rows[i]);
|
381
|
+
$row = $( $tb[ k ].rows[ i ] );
|
348
382
|
cols = [];
|
349
383
|
// if this is a child row, add it to the last row's children and continue to the next row
|
350
384
|
// ignore child row class, if it is the first row
|
351
|
-
if ($row.hasClass(c.cssChildRow) && i !== 0) {
|
385
|
+
if ( $row.hasClass( c.cssChildRow ) && i !== 0 ) {
|
352
386
|
t = cc.normalized.length - 1;
|
353
|
-
|
387
|
+
prevRowData = cc.normalized[ t ][ c.columns ];
|
388
|
+
prevRowData.$row = prevRowData.$row.add( $row );
|
354
389
|
// add 'hasChild' class name to parent row
|
355
|
-
if (!$row.prev().hasClass(c.cssChildRow)) {
|
356
|
-
$row.prev().addClass(ts.css.cssHasChild);
|
390
|
+
if ( !$row.prev().hasClass( c.cssChildRow ) ) {
|
391
|
+
$row.prev().addClass( ts.css.cssHasChild );
|
357
392
|
}
|
358
393
|
// save child row content (un-parsed!)
|
359
|
-
|
394
|
+
v = $row.children( 'th, td' );
|
395
|
+
t = prevRowData.child.length;
|
396
|
+
prevRowData.child[ t ] = [];
|
397
|
+
// child row content does not account for colspans/rowspans; so indexing may be off
|
398
|
+
for ( j = 0; j < c.columns; j++ ) {
|
399
|
+
prevRowData.child[ t ][ j ] = getParsedText( c, v[ j ], j );
|
400
|
+
}
|
360
401
|
// go to the next for loop
|
361
402
|
continue;
|
362
403
|
}
|
363
404
|
rowData.$row = $row;
|
364
405
|
rowData.order = i; // add original row position to rowCache
|
365
|
-
for (j = 0; j < c.columns; ++j) {
|
366
|
-
if (typeof parsers[j] === 'undefined') {
|
367
|
-
if (c.debug) {
|
368
|
-
log('No parser found for cell:', $row[0].cells[j], 'does it have a header?');
|
406
|
+
for ( j = 0; j < c.columns; ++j ) {
|
407
|
+
if (typeof parsers[ j ] === 'undefined') {
|
408
|
+
if ( c.debug ) {
|
409
|
+
log( 'No parser found for cell:', $row[ 0 ].cells[ j ], 'does it have a header?' );
|
369
410
|
}
|
370
411
|
continue;
|
371
412
|
}
|
372
|
-
t = ts.getElementText(c, $row[0].cells[j], j);
|
373
|
-
rowData.raw.push(t); // save original row text
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
} else {
|
378
|
-
tx = extractors[j].format(t, table, $row[0].cells[j], j);
|
379
|
-
}
|
380
|
-
// allow parsing if the string is empty, previously parsing would change it to zero,
|
381
|
-
// in case the parser needs to extract data from the table cell attributes
|
382
|
-
v = parsers[j].id === 'no-parser' ? '' : parsers[j].format(tx, table, $row[0].cells[j], j);
|
383
|
-
cols.push( c.ignoreCase && typeof v === 'string' ? v.toLowerCase() : v );
|
384
|
-
if ((parsers[j].type || '').toLowerCase() === 'numeric') {
|
413
|
+
t = ts.getElementText( c, $row[ 0 ].cells[j], j );
|
414
|
+
rowData.raw.push( t ); // save original row text
|
415
|
+
v = getParsedText( c, $row[ 0 ].cells[ j ], j, t );
|
416
|
+
cols.push( v );
|
417
|
+
if ( ( parsers[ j ].type || '' ).toLowerCase() === 'numeric' ) {
|
385
418
|
// determine column max value (ignore sign)
|
386
|
-
colMax[j] = Math.max(Math.abs(v) || 0, colMax[j] || 0);
|
419
|
+
colMax[ j ] = Math.max( Math.abs( v ) || 0, colMax[ j ] || 0 );
|
387
420
|
}
|
388
421
|
}
|
389
422
|
// ensure rowData is always in the same location (after the last column)
|
390
|
-
cols[c.columns] = rowData;
|
391
|
-
cc.normalized.push(cols);
|
423
|
+
cols[ c.columns ] = rowData;
|
424
|
+
cc.normalized.push( cols );
|
392
425
|
}
|
393
426
|
cc.colMax = colMax;
|
394
427
|
// total up rows, not including child rows
|
395
428
|
c.totalRows += cc.normalized.length;
|
396
429
|
|
397
430
|
}
|
398
|
-
if (c.showProcessing) {
|
399
|
-
ts.isProcessing(table); // remove processing icon
|
431
|
+
if ( c.showProcessing ) {
|
432
|
+
ts.isProcessing( table ); // remove processing icon
|
400
433
|
}
|
401
|
-
if (c.debug) {
|
402
|
-
benchmark('Building cache for ' + totalRows + ' rows', cacheTime);
|
434
|
+
if ( c.debug ) {
|
435
|
+
benchmark( 'Building cache for ' + totalRows + ' rows', cacheTime );
|
403
436
|
}
|
404
437
|
}
|
405
438
|
|
@@ -539,14 +572,15 @@
|
|
539
572
|
}
|
540
573
|
|
541
574
|
function updateHeader(table) {
|
542
|
-
var s, $th, col,
|
543
|
-
c = table.config
|
544
|
-
|
545
|
-
|
575
|
+
var index, s, $th, col,
|
576
|
+
c = table.config,
|
577
|
+
len = c.$headers.length;
|
578
|
+
for ( index = 0; index < len; index++ ) {
|
579
|
+
$th = c.$headers.eq( index );
|
546
580
|
col = ts.getColumnData( table, c.headers, index, true );
|
547
581
|
// add 'sorter-false' class if 'parser-false' is set
|
548
|
-
s = ts.getData( th, col, 'sorter' ) === 'false' || ts.getData( th, col, 'parser' ) === 'false';
|
549
|
-
th.sortDisabled = s;
|
582
|
+
s = ts.getData( $th, col, 'sorter' ) === 'false' || ts.getData( $th, col, 'parser' ) === 'false';
|
583
|
+
$th[0].sortDisabled = s;
|
550
584
|
$th[ s ? 'addClass' : 'removeClass' ]('sorter-false').attr('aria-disabled', '' + s);
|
551
585
|
// aria-controls - requires table ID
|
552
586
|
if (table.id) {
|
@@ -556,11 +590,11 @@
|
|
556
590
|
$th.attr('aria-controls', table.id);
|
557
591
|
}
|
558
592
|
}
|
559
|
-
}
|
593
|
+
}
|
560
594
|
}
|
561
595
|
|
562
596
|
function setHeadersCss(table) {
|
563
|
-
var f, i, j,
|
597
|
+
var f, h, i, j, $headers, $h, nextSort, txt,
|
564
598
|
c = table.config,
|
565
599
|
list = c.sortList,
|
566
600
|
len = list.length,
|
@@ -604,14 +638,19 @@
|
|
604
638
|
}
|
605
639
|
}
|
606
640
|
// add verbose aria labels
|
607
|
-
c.$headers.
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
641
|
+
len = c.$headers.length;
|
642
|
+
$headers = c.$headers.not('.sorter-false');
|
643
|
+
for ( i = 0; i < len; i++ ) {
|
644
|
+
$h = $headers.eq( i );
|
645
|
+
if ( $h.length ) {
|
646
|
+
h = $headers[ i ];
|
647
|
+
nextSort = h.order[ ( h.count + 1 ) % ( c.sortReset ? 3 : 2 ) ],
|
648
|
+
txt = $.trim( $h.text() ) + ': ' +
|
649
|
+
ts.language[ $h.hasClass( ts.css.sortAsc ) ? 'sortAsc' : $h.hasClass( ts.css.sortDesc ) ? 'sortDesc' : 'sortNone' ] +
|
612
650
|
ts.language[ nextSort === 0 ? 'nextAsc' : nextSort === 1 ? 'nextDesc' : 'nextNone' ];
|
613
|
-
|
614
|
-
|
651
|
+
$h.attr( 'aria-label', txt );
|
652
|
+
}
|
653
|
+
}
|
615
654
|
}
|
616
655
|
|
617
656
|
function updateHeaderSortCount( table, list ) {
|
@@ -624,9 +663,10 @@
|
|
624
663
|
val = sortList[indx];
|
625
664
|
// ensure all sortList values are numeric - fixes #127
|
626
665
|
col = parseInt(val[0], 10);
|
627
|
-
//
|
628
|
-
|
629
|
-
|
666
|
+
// prevents error if sorton array is wrong
|
667
|
+
if ( col < c.columns && c.$headerIndexed[col] ) {
|
668
|
+
// make sure header exists
|
669
|
+
header = c.$headerIndexed[col][0];
|
630
670
|
// o.count = o.count + 1;
|
631
671
|
dir = ('' + val[1]).match(/^(1|d|s|o|n)/);
|
632
672
|
dir = dir ? dir[0] : '';
|
@@ -670,10 +710,11 @@
|
|
670
710
|
// let any updates complete before initializing a sort
|
671
711
|
return setTimeout(function(){ initSort(table, cell, event); }, 50);
|
672
712
|
}
|
673
|
-
var arry, indx, col, order, s,
|
713
|
+
var arry, indx, i, col, order, s, $header,
|
674
714
|
c = table.config,
|
675
715
|
key = !event[c.sortMultiSortKey],
|
676
|
-
$table = c.$table
|
716
|
+
$table = c.$table,
|
717
|
+
len = c.$headers.length;
|
677
718
|
// Only call sortStart if sorting is enabled
|
678
719
|
$table.trigger('sortStart', table);
|
679
720
|
// get current column sort order
|
@@ -681,12 +722,13 @@
|
|
681
722
|
// reset all sorts on non-current column - issue #30
|
682
723
|
if (c.sortRestart) {
|
683
724
|
indx = cell;
|
684
|
-
|
725
|
+
for ( i = 0; i < len; i++ ) {
|
726
|
+
$header = c.$headers.eq( i );
|
685
727
|
// only reset counts on columns that weren't just clicked on and if not included in a multisort
|
686
|
-
if (
|
687
|
-
|
728
|
+
if ( $header[0] !== indx && ( key || !$header.is('.' + ts.css.sortDesc + ',.' + ts.css.sortAsc) ) ) {
|
729
|
+
$header[0].count = -1;
|
688
730
|
}
|
689
|
-
}
|
731
|
+
}
|
690
732
|
}
|
691
733
|
// get current column index
|
692
734
|
indx = parseInt( $(cell).attr('data-column'), 10 );
|
@@ -912,35 +954,31 @@
|
|
912
954
|
table.isUpdating = true;
|
913
955
|
$table.find(c.selectorRemove).remove();
|
914
956
|
// get position from the dom
|
915
|
-
var
|
957
|
+
var t, row, icell, cache,
|
916
958
|
$tb = c.$tbodies,
|
917
959
|
$cell = $(cell),
|
918
960
|
// update cache - format: function(s, table, cell, cellIndex)
|
919
961
|
// no closest in jQuery v1.2.6 - tbdy = $tb.index( $(cell).closest('tbody') ),$row = $(cell).closest('tr');
|
920
962
|
tbdy = $tb.index( $.fn.closest ? $cell.closest('tbody') : $cell.parents('tbody').filter(':first') ),
|
963
|
+
tbcache = c.cache[ tbdy ],
|
921
964
|
$row = $.fn.closest ? $cell.closest('tr') : $cell.parents('tr').filter(':first');
|
922
965
|
cell = $cell[0]; // in case cell is a jQuery object
|
923
966
|
// tbody may not exist if update is initialized while tbody is removed for processing
|
924
967
|
if ($tb.length && tbdy >= 0) {
|
925
|
-
row = $tb.eq(tbdy).find('tr').index( $row );
|
968
|
+
row = $tb.eq( tbdy ).find( 'tr' ).index( $row );
|
969
|
+
cache = tbcache.normalized[ row ];
|
926
970
|
icell = $cell.index();
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
t = c.extractors[icell].format( ts.getElementText(c, cell, icell), table, cell, icell );
|
932
|
-
}
|
933
|
-
v = c.parsers[icell].id === 'no-parser' ? '' :
|
934
|
-
c.parsers[icell].format( t, table, cell, icell );
|
935
|
-
c.cache[tbdy].normalized[row][icell] = c.ignoreCase && typeof v === 'string' ? v.toLowerCase() : v;
|
936
|
-
if ((c.parsers[icell].type || '').toLowerCase() === 'numeric') {
|
971
|
+
t = getParsedText( c, cell, icell );
|
972
|
+
cache[ icell ] = t;
|
973
|
+
cache[ c.columns ].$row = $row;
|
974
|
+
if ( (c.parsers[icell].type || '').toLowerCase() === 'numeric' ) {
|
937
975
|
// update column max value (ignore sign)
|
938
|
-
|
976
|
+
tbcache.colMax[icell] = Math.max(Math.abs(t) || 0, tbcache.colMax[icell] || 0);
|
939
977
|
}
|
940
|
-
|
941
|
-
if (
|
978
|
+
t = resort !== 'undefined' ? resort : c.resort;
|
979
|
+
if (t !== false) {
|
942
980
|
// widgets will be reapplied
|
943
|
-
checkResort(c,
|
981
|
+
checkResort(c, t, callback);
|
944
982
|
} else {
|
945
983
|
// don't reapply widgets is resort is false, just in case it causes
|
946
984
|
// problems with element focus
|
@@ -960,7 +998,7 @@
|
|
960
998
|
commonUpdate(table, resort, callback);
|
961
999
|
} else {
|
962
1000
|
$row = $($row).attr('role', 'row'); // make sure we're using a jQuery object
|
963
|
-
var i, j, l,
|
1001
|
+
var i, j, l, rowData, cells,
|
964
1002
|
rows = $row.filter('tr').length,
|
965
1003
|
tbdy = c.$tbodies.index( $row.parents('tbody').filter(':first') );
|
966
1004
|
// fixes adding rows to an empty table - see issue #179
|
@@ -978,14 +1016,7 @@
|
|
978
1016
|
};
|
979
1017
|
// add each cell
|
980
1018
|
for (j = 0; j < l; j++) {
|
981
|
-
|
982
|
-
t = ts.getElementText(c, $row[i].cells[j], j);
|
983
|
-
} else {
|
984
|
-
t = c.extractors[j].format( ts.getElementText(c, $row[i].cells[j], j), table, $row[i].cells[j], j );
|
985
|
-
}
|
986
|
-
v = c.parsers[j].id === 'no-parser' ? '' :
|
987
|
-
c.parsers[j].format( t, table, $row[i].cells[j], j );
|
988
|
-
cells[j] = c.ignoreCase && typeof v === 'string' ? v.toLowerCase() : v;
|
1019
|
+
cells[j] = getParsedText( c, $row[i].cells[j], j );
|
989
1020
|
if ((c.parsers[j].type || '').toLowerCase() === 'numeric') {
|
990
1021
|
// update column max value (ignore sign)
|
991
1022
|
c.cache[tbdy].colMax[j] = Math.max(Math.abs(cells[j]) || 0, c.cache[tbdy].colMax[j] || 0);
|
@@ -1213,7 +1244,7 @@
|
|
1213
1244
|
// automatically add a colgroup with col elements set to a percentage width
|
1214
1245
|
ts.fixColumnWidth = function(table) {
|
1215
1246
|
table = $(table)[0];
|
1216
|
-
var overallWidth, percent,
|
1247
|
+
var overallWidth, percent, $tbodies, len, index,
|
1217
1248
|
c = table.config,
|
1218
1249
|
colgroup = c.$table.children('colgroup');
|
1219
1250
|
// remove plugin-added colgroup, in case we need to refresh the widths
|
@@ -1224,10 +1255,12 @@
|
|
1224
1255
|
colgroup = $('<colgroup class="' + ts.css.colgroup + '">');
|
1225
1256
|
overallWidth = c.$table.width();
|
1226
1257
|
// only add col for visible columns - fixes #371
|
1227
|
-
c.$tbodies.find('tr:first').children(':visible')
|
1228
|
-
|
1258
|
+
$tbodies = c.$tbodies.find('tr:first').children(':visible'); //.each(function()
|
1259
|
+
len = $tbodies.length;
|
1260
|
+
for ( index = 0; index < len; index++ ) {
|
1261
|
+
percent = parseInt( ( $tbodies.eq( index ).width() / overallWidth ) * 1000, 10 ) / 10 + '%';
|
1229
1262
|
colgroup.append( $('<col>').css('width', percent) );
|
1230
|
-
}
|
1263
|
+
}
|
1231
1264
|
c.$table.prepend(colgroup);
|
1232
1265
|
}
|
1233
1266
|
};
|
@@ -1262,9 +1295,10 @@
|
|
1262
1295
|
// http://www.javascripttoolbox.com/lib/table/examples.php
|
1263
1296
|
// http://www.javascripttoolbox.com/temp/table_cellindex.html
|
1264
1297
|
ts.computeColumnIndex = function(trs) {
|
1265
|
-
var
|
1266
|
-
|
1267
|
-
|
1298
|
+
var i, j, k, l, $cell, cell, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol,
|
1299
|
+
matrix = [],
|
1300
|
+
matrixrow = [],
|
1301
|
+
lookup = {};
|
1268
1302
|
for (i = 0; i < trs.length; i++) {
|
1269
1303
|
cells = trs[i].cells;
|
1270
1304
|
for (j = 0; j < cells.length; j++) {
|
@@ -1344,7 +1378,7 @@
|
|
1344
1378
|
$(table)[0].config.$tbodies.children().detach();
|
1345
1379
|
};
|
1346
1380
|
|
1347
|
-
ts.bindEvents = function(table, $headers, core){
|
1381
|
+
ts.bindEvents = function(table, $headers, core) {
|
1348
1382
|
table = $(table)[0];
|
1349
1383
|
var t, downTarget = null,
|
1350
1384
|
c = table.config;
|
@@ -1355,28 +1389,35 @@
|
|
1355
1389
|
$(t).addClass( c.namespace.slice(1) + '_extra_table' );
|
1356
1390
|
}
|
1357
1391
|
}
|
1392
|
+
t = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
|
1393
|
+
.replace(/\s+/g, ' ')
|
1394
|
+
.split(' ')
|
1395
|
+
.join(c.namespace + ' ');
|
1358
1396
|
// apply event handling to headers and/or additional headers (stickyheaders, scroller, etc)
|
1359
1397
|
$headers
|
1360
1398
|
// http://stackoverflow.com/questions/5312849/jquery-find-self;
|
1361
1399
|
.find(c.selectorSort).add( $headers.filter(c.selectorSort) )
|
1362
|
-
.unbind(
|
1363
|
-
.bind(
|
1400
|
+
.unbind(t)
|
1401
|
+
.bind(t, function(e, external) {
|
1364
1402
|
var cell,
|
1365
1403
|
$target = $(e.target),
|
1366
|
-
type
|
1404
|
+
// wrap event type in spaces, so the match doesn't trigger on inner words
|
1405
|
+
type = ' ' + e.type + ' ';
|
1367
1406
|
// only recognize left clicks
|
1368
|
-
if ( ( ( e.which || e.button ) !== 1 &&
|
1407
|
+
if ( ( ( e.which || e.button ) !== 1 && !type.match( ' ' + c.pointerClick + ' | sort | keyup ' ) ) ||
|
1369
1408
|
// allow pressing enter
|
1370
|
-
( type === 'keyup' && e.which !== 13 ) ||
|
1409
|
+
( type === ' keyup ' && e.which !== 13 ) ||
|
1371
1410
|
// allow triggering a click event (e.which is undefined) & ignore physical clicks
|
1372
|
-
( type
|
1411
|
+
( type.match(' ' + c.pointerClick + ' ') && typeof e.which !== 'undefined' ) ) {
|
1373
1412
|
return;
|
1374
1413
|
}
|
1375
1414
|
// ignore mouseup if mousedown wasn't on the same target
|
1376
|
-
if ( type
|
1415
|
+
if ( type.match(' ' + c.pointerUp + ' ') && downTarget !== e.target && external !== true ) { return; }
|
1377
1416
|
// set timer on mousedown
|
1378
|
-
if ( type
|
1417
|
+
if ( type.match(' ' + c.pointerDown + ' ') ) {
|
1379
1418
|
downTarget = e.target;
|
1419
|
+
// needed or jQuery v1.2.6 throws an error
|
1420
|
+
e.preventDefault();
|
1380
1421
|
return;
|
1381
1422
|
}
|
1382
1423
|
downTarget = null;
|
@@ -1411,17 +1452,20 @@
|
|
1411
1452
|
|
1412
1453
|
// restore headers
|
1413
1454
|
ts.restoreHeaders = function(table){
|
1414
|
-
var $cell,
|
1415
|
-
c = $(table)[0].config
|
1455
|
+
var index, $cell,
|
1456
|
+
c = $(table)[0].config,
|
1457
|
+
$headers = c.$table.find( c.selectorHeaders ),
|
1458
|
+
len = $headers.length;
|
1416
1459
|
// don't use c.$headers here in case header cells were swapped
|
1417
|
-
|
1418
|
-
|
1460
|
+
for ( index = 0; index < len; index++ ) {
|
1461
|
+
// c.$table.find(c.selectorHeaders).each(function(i){
|
1462
|
+
$cell = $headers.eq( index );
|
1419
1463
|
// only restore header cells if it is wrapped
|
1420
1464
|
// because this is also used by the updateAll method
|
1421
|
-
if ($cell.find('.' + ts.css.headerIn).length){
|
1422
|
-
$cell.html( c.headerContent[
|
1465
|
+
if ( $cell.find( '.' + ts.css.headerIn ).length ) {
|
1466
|
+
$cell.html( c.headerContent[ index ] );
|
1423
1467
|
}
|
1424
|
-
}
|
1468
|
+
}
|
1425
1469
|
};
|
1426
1470
|
|
1427
1471
|
ts.destroy = function(table, removeClasses, callback){
|
@@ -1581,8 +1625,8 @@
|
|
1581
1625
|
'E' : '\u00c9\u00c8\u00ca\u00cb\u011a\u0118', // ÉÈÊËĚĘ
|
1582
1626
|
'i' : '\u00ed\u00ec\u0130\u00ee\u00ef\u0131', // íìİîïı
|
1583
1627
|
'I' : '\u00cd\u00cc\u0130\u00ce\u00cf', // ÍÌİÎÏ
|
1584
|
-
'o' : '\u00f3\u00f2\u00f4\u00f5\u00f6', //
|
1585
|
-
'O' : '\u00d3\u00d2\u00d4\u00d5\u00d6', //
|
1628
|
+
'o' : '\u00f3\u00f2\u00f4\u00f5\u00f6\u014d', // óòôõöō
|
1629
|
+
'O' : '\u00d3\u00d2\u00d4\u00d5\u00d6\u014c', // ÓÒÔÕÖŌ
|
1586
1630
|
'ss': '\u00df', // ß (s sharp)
|
1587
1631
|
'SS': '\u1e9e', // ẞ (Capital sharp s)
|
1588
1632
|
'u' : '\u00fa\u00f9\u00fb\u00fc\u016f', // úùûüů
|
@@ -1922,7 +1966,7 @@
|
|
1922
1966
|
|
1923
1967
|
ts.isDigit = function(s) {
|
1924
1968
|
// replace all unwanted chars and match
|
1925
|
-
return isNaN(s) ? (/^[\-+(]?\d+[)]?$/).test(s.toString().replace(/[,.'"\s]/g, '')) :
|
1969
|
+
return isNaN(s) ? (/^[\-+(]?\d+[)]?$/).test(s.toString().replace(/[,.'"\s]/g, '')) : s !== '';
|
1926
1970
|
};
|
1927
1971
|
|
1928
1972
|
}()
|
@@ -2108,7 +2152,7 @@
|
|
2108
2152
|
id: 'zebra',
|
2109
2153
|
priority: 90,
|
2110
2154
|
format: function(table, c, wo) {
|
2111
|
-
var $
|
2155
|
+
var $tv, $tr, row, even, time, k, i, len,
|
2112
2156
|
child = new RegExp(c.cssChildRow, 'i'),
|
2113
2157
|
b = c.$tbodies.add( $( c.namespace + '_extra_table' ).children( 'tbody' ) );
|
2114
2158
|
if (c.debug) {
|
@@ -2117,17 +2161,17 @@
|
|
2117
2161
|
for (k = 0; k < b.length; k++ ) {
|
2118
2162
|
// loop through the visible rows
|
2119
2163
|
row = 0;
|
2120
|
-
$
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2124
|
-
$tv.each(function(){
|
2125
|
-
$tr = $(this);
|
2164
|
+
$tv = b.eq( k ).children( 'tr:visible' ).not( c.selectorRemove );
|
2165
|
+
len = $tv.length;
|
2166
|
+
for ( i = 0; i < len; i++ ) {
|
2167
|
+
$tr = $tv.eq( i );
|
2126
2168
|
// style child rows the same way the parent row was styled
|
2127
|
-
if (!child.test(
|
2128
|
-
even = (row % 2 === 0);
|
2129
|
-
$tr
|
2130
|
-
|
2169
|
+
if ( !child.test( $tr[0].className ) ) { row++; }
|
2170
|
+
even = ( row % 2 === 0 );
|
2171
|
+
$tr
|
2172
|
+
.removeClass( wo.zebra[ even ? 1 : 0 ] )
|
2173
|
+
.addClass( wo.zebra[ even ? 0 : 1 ] );
|
2174
|
+
}
|
2131
2175
|
}
|
2132
2176
|
},
|
2133
2177
|
remove: function(table, c, wo, refreshing){
|
@@ -2149,7 +2193,7 @@
|
|
2149
2193
|
;(function ($, window, document) {
|
2150
2194
|
'use strict';
|
2151
2195
|
|
2152
|
-
var ts = $.tablesorter
|
2196
|
+
var ts = $.tablesorter || {};
|
2153
2197
|
// *** Store data in local storage, with a cookie fallback ***
|
2154
2198
|
/* IE7 needs JSON library for JSON.stringify - (http://caniuse.com/#search=json)
|
2155
2199
|
if you need it, then include https://github.com/douglascrockford/JSON-js
|
@@ -2238,7 +2282,7 @@ ts.storage = function(table, key, value, options) {
|
|
2238
2282
|
/*! Widget: uitheme - updated 3/26/2015 (v2.21.3) */
|
2239
2283
|
;(function ($) {
|
2240
2284
|
'use strict';
|
2241
|
-
var ts = $.tablesorter
|
2285
|
+
var ts = $.tablesorter || {};
|
2242
2286
|
|
2243
2287
|
ts.themes = {
|
2244
2288
|
'bootstrap' : {
|
@@ -2424,7 +2468,7 @@ ts.addWidget({
|
|
2424
2468
|
/*! Widget: columns */
|
2425
2469
|
;(function ($) {
|
2426
2470
|
'use strict';
|
2427
|
-
var ts = $.tablesorter
|
2471
|
+
var ts = $.tablesorter || {};
|
2428
2472
|
|
2429
2473
|
ts.addWidget({
|
2430
2474
|
id: "columns",
|
@@ -2500,16 +2544,16 @@ ts.addWidget({
|
|
2500
2544
|
|
2501
2545
|
})(jQuery);
|
2502
2546
|
|
2503
|
-
/*! Widget: filter - updated
|
2547
|
+
/*! Widget: filter - updated 5/17/2015 (v2.22.0) *//*
|
2504
2548
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
2505
2549
|
* by Rob Garrison
|
2506
2550
|
*/
|
2507
|
-
;(function ($) {
|
2551
|
+
;( function ( $ ) {
|
2508
2552
|
'use strict';
|
2509
|
-
var ts = $.tablesorter
|
2553
|
+
var ts = $.tablesorter || {},
|
2510
2554
|
tscss = ts.css;
|
2511
2555
|
|
2512
|
-
$.extend(tscss, {
|
2556
|
+
$.extend( tscss, {
|
2513
2557
|
filterRow : 'tablesorter-filter-row',
|
2514
2558
|
filter : 'tablesorter-filter',
|
2515
2559
|
filterDisabled : 'disabled',
|
@@ -2517,26 +2561,27 @@ $.extend(tscss, {
|
|
2517
2561
|
});
|
2518
2562
|
|
2519
2563
|
ts.addWidget({
|
2520
|
-
id:
|
2564
|
+
id: 'filter',
|
2521
2565
|
priority: 50,
|
2522
2566
|
options : {
|
2523
2567
|
filter_childRows : false, // if true, filter includes child row content in the search
|
2568
|
+
filter_childByColumn : false, // ( filter_childRows must be true ) if true = search child rows by column; false = search all child row text grouped
|
2524
2569
|
filter_columnFilters : true, // if true, a filter will be added to the top of each table column
|
2525
|
-
filter_columnAnyMatch: true, // if true, allows using
|
2526
|
-
filter_cellFilter : '', // css class name added to the filter cell (string or array)
|
2527
|
-
filter_cssFilter : '', // css class name added to the filter row & each input in the row (tablesorter-filter is ALWAYS added)
|
2528
|
-
filter_defaultFilter : {}, // add a default column filter type
|
2570
|
+
filter_columnAnyMatch: true, // if true, allows using '#:{query}' in AnyMatch searches ( column:query )
|
2571
|
+
filter_cellFilter : '', // css class name added to the filter cell ( string or array )
|
2572
|
+
filter_cssFilter : '', // css class name added to the filter row & each input in the row ( tablesorter-filter is ALWAYS added )
|
2573
|
+
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.
|
2529
2574
|
filter_excludeFilter : {}, // filters to exclude, per column
|
2530
|
-
filter_external : '', // jQuery selector string (or jQuery object) of external filters
|
2575
|
+
filter_external : '', // jQuery selector string ( or jQuery object ) of external filters
|
2531
2576
|
filter_filteredRow : 'filtered', // class added to filtered rows; needed by pager plugin
|
2532
2577
|
filter_formatter : null, // add custom filter elements to the filter row
|
2533
2578
|
filter_functions : null, // add custom filter functions using this option
|
2534
2579
|
filter_hideEmpty : true, // hide filter row when table is empty
|
2535
2580
|
filter_hideFilters : false, // collapse filter row when mouse leaves the area
|
2536
2581
|
filter_ignoreCase : true, // if true, make all searches case-insensitive
|
2537
|
-
filter_liveSearch : true, // if true, search column content while the user types (with a delay)
|
2538
|
-
filter_onlyAvail : 'filter-onlyAvail', // a header with a select dropdown & this class name will only show available (visible) options within the drop down
|
2539
|
-
filter_placeholder : { search : '', select : '' }, // default placeholder text (overridden by any header
|
2582
|
+
filter_liveSearch : true, // if true, search column content while the user types ( with a delay )
|
2583
|
+
filter_onlyAvail : 'filter-onlyAvail', // a header with a select dropdown & this class name will only show available ( visible ) options within the drop down
|
2584
|
+
filter_placeholder : { search : '', select : '' }, // default placeholder text ( overridden by any header 'data-placeholder' setting )
|
2540
2585
|
filter_reset : null, // jQuery selector string of an element used to reset the filters
|
2541
2586
|
filter_saveFilters : false, // Use the $.tablesorter.storage utility to save the most recent filters
|
2542
2587
|
filter_searchDelay : 300, // typing delay in milliseconds before starting a search
|
@@ -2548,37 +2593,38 @@ ts.addWidget({
|
|
2548
2593
|
filter_defaultAttrib : 'data-value', // data attribute in the header cell that contains the default filter value
|
2549
2594
|
filter_selectSourceSeparator : '|' // filter_selectSource array text left of the separator is added to the option value, right into the option text
|
2550
2595
|
},
|
2551
|
-
format: function(table, c, wo) {
|
2552
|
-
if (!c.$table.hasClass('hasFilters')) {
|
2553
|
-
ts.filter.init(table, c, wo);
|
2596
|
+
format: function( table, c, wo ) {
|
2597
|
+
if ( !c.$table.hasClass( 'hasFilters' ) ) {
|
2598
|
+
ts.filter.init( table, c, wo );
|
2554
2599
|
}
|
2555
2600
|
},
|
2556
|
-
remove: function(table, c, wo, refreshing) {
|
2601
|
+
remove: function( table, c, wo, refreshing ) {
|
2557
2602
|
var tbodyIndex, $tbody,
|
2558
2603
|
$table = c.$table,
|
2559
2604
|
$tbodies = c.$tbodies,
|
2560
|
-
events = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
|
2605
|
+
events = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
|
2606
|
+
.split( ' ' ).join( c.namespace + 'filter ' );
|
2561
2607
|
$table
|
2562
|
-
.removeClass('hasFilters')
|
2608
|
+
.removeClass( 'hasFilters' )
|
2563
2609
|
// add .tsfilter namespace to all BUT search
|
2564
|
-
.unbind( events.replace(/\s+/g, ' ') )
|
2610
|
+
.unbind( events.replace( /\s+/g, ' ' ) )
|
2565
2611
|
// remove the filter row even if refreshing, because the column might have been moved
|
2566
|
-
.find('.' + tscss.filterRow).remove();
|
2567
|
-
if (refreshing) { return; }
|
2568
|
-
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
|
2569
|
-
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
|
2570
|
-
$tbody.children().removeClass(wo.filter_filteredRow).show();
|
2571
|
-
ts.processTbody(table, $tbody, false); // restore tbody
|
2612
|
+
.find( '.' + tscss.filterRow ).remove();
|
2613
|
+
if ( refreshing ) { return; }
|
2614
|
+
for ( tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
|
2615
|
+
$tbody = ts.processTbody( table, $tbodies.eq( tbodyIndex ), true ); // remove tbody
|
2616
|
+
$tbody.children().removeClass( wo.filter_filteredRow ).show();
|
2617
|
+
ts.processTbody( table, $tbody, false ); // restore tbody
|
2572
2618
|
}
|
2573
|
-
if (wo.filter_reset) {
|
2574
|
-
$(document).undelegate(wo.filter_reset, 'click.tsfilter');
|
2619
|
+
if ( wo.filter_reset ) {
|
2620
|
+
$( document ).undelegate( wo.filter_reset, 'click.tsfilter' );
|
2575
2621
|
}
|
2576
2622
|
}
|
2577
2623
|
});
|
2578
2624
|
|
2579
2625
|
ts.filter = {
|
2580
2626
|
|
2581
|
-
// regex used in filter
|
2627
|
+
// regex used in filter 'check' functions - not for general use and not documented
|
2582
2628
|
regex: {
|
2583
2629
|
regex : /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/, // regex to test for regex
|
2584
2630
|
child : /tablesorter-childRow/, // child row class name; this gets updated in the script
|
@@ -2591,22 +2637,33 @@ ts.filter = {
|
|
2591
2637
|
},
|
2592
2638
|
// function( c, data ) { }
|
2593
2639
|
// c = table.config
|
2594
|
-
// data
|
2595
|
-
// data
|
2596
|
-
// data.
|
2597
|
-
// data.
|
2598
|
-
// data.
|
2599
|
-
// data.
|
2600
|
-
// data.
|
2640
|
+
// data.$row = jQuery object of the row currently being processed
|
2641
|
+
// data.$cells = jQuery object of all cells within the current row
|
2642
|
+
// data.filters = array of filters for all columns ( some may be undefined )
|
2643
|
+
// data.filter = filter for the current column
|
2644
|
+
// data.iFilter = same as data.filter, except lowercase ( if wo.filter_ignoreCase is true )
|
2645
|
+
// data.exact = table cell text ( or parsed data if column parser enabled )
|
2646
|
+
// data.iExact = same as data.exact, except lowercase ( if wo.filter_ignoreCase is true )
|
2647
|
+
// data.cache = table cell text from cache, so it has been parsed ( & in all lower case if c.ignoreCase is true )
|
2648
|
+
// data.cacheArray = An array of parsed content from each table cell in the row being processed
|
2649
|
+
// data.index = column index; table = table element ( DOM )
|
2650
|
+
// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
|
2601
2651
|
types: {
|
2602
2652
|
// Look for regex
|
2603
2653
|
regex: function( c, data ) {
|
2604
|
-
if ( ts.filter.regex.regex.test(data.
|
2654
|
+
if ( ts.filter.regex.regex.test( data.filter ) ) {
|
2605
2655
|
var matches,
|
2606
|
-
regex
|
2656
|
+
// cache regex per column for optimal speed
|
2657
|
+
regex = data.filter_regexCache[ data.index ] || ts.filter.regex.regex.exec( data.filter ),
|
2658
|
+
isRegex = regex instanceof RegExp;
|
2607
2659
|
try {
|
2608
|
-
|
2609
|
-
|
2660
|
+
if ( !isRegex ) {
|
2661
|
+
// force case insensitive search if ignoreCase option set?
|
2662
|
+
// if ( c.ignoreCase && !regex[2] ) { regex[2] = 'i'; }
|
2663
|
+
data.filter_regexCache[ data.index ] = regex = new RegExp( regex[1], regex[2] );
|
2664
|
+
}
|
2665
|
+
matches = regex.test( data.exact );
|
2666
|
+
} catch ( error ) {
|
2610
2667
|
matches = false;
|
2611
2668
|
}
|
2612
2669
|
return matches;
|
@@ -2615,46 +2672,56 @@ ts.filter = {
|
|
2615
2672
|
},
|
2616
2673
|
// Look for operators >, >=, < or <=
|
2617
2674
|
operators: function( c, data ) {
|
2618
|
-
|
2619
|
-
|
2675
|
+
// ignore empty strings... because '' < 10 is true
|
2676
|
+
if ( /^[<>]=?/.test( data.iFilter ) && data.iExact !== '' ) {
|
2677
|
+
var cachedValue, result, txt,
|
2620
2678
|
table = c.table,
|
2621
2679
|
index = data.index,
|
2622
2680
|
parsed = data.parsed[index],
|
2623
|
-
query = ts.formatFloat( data.iFilter.replace(ts.filter.regex.operators, ''), table ),
|
2681
|
+
query = ts.formatFloat( data.iFilter.replace( ts.filter.regex.operators, '' ), table ),
|
2624
2682
|
parser = c.parsers[index],
|
2625
2683
|
savedSearch = query;
|
2626
|
-
// parse filter value in case we're comparing numbers (dates)
|
2627
|
-
if (parsed || parser.type === 'numeric') {
|
2628
|
-
|
2629
|
-
|
2684
|
+
// parse filter value in case we're comparing numbers ( dates )
|
2685
|
+
if ( parsed || parser.type === 'numeric' ) {
|
2686
|
+
txt = $.trim( '' + data.iFilter.replace( ts.filter.regex.operators, '' ) );
|
2687
|
+
result = ts.filter.parseFilter( c, txt, index, true );
|
2688
|
+
query = ( typeof result === 'number' && result !== '' && !isNaN( result ) ) ? result : query;
|
2630
2689
|
}
|
2631
|
-
|
2632
2690
|
// iExact may be numeric - see issue #149;
|
2633
|
-
// check if cached is defined, because sometimes j goes out of range? (numeric columns)
|
2634
|
-
|
2635
|
-
|
2636
|
-
|
2637
|
-
|
2638
|
-
|
2639
|
-
|
2691
|
+
// check if cached is defined, because sometimes j goes out of range? ( numeric columns )
|
2692
|
+
if ( ( parsed || parser.type === 'numeric' ) && !isNaN( query ) &&
|
2693
|
+
typeof data.cache !== 'undefined' ) {
|
2694
|
+
cachedValue = data.cache;
|
2695
|
+
} else {
|
2696
|
+
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.filter.regex.nondigit, '' ) : data.iExact;
|
2697
|
+
cachedValue = ts.formatFloat( txt, table );
|
2698
|
+
}
|
2699
|
+
if ( />/.test( data.iFilter ) ) {
|
2700
|
+
result = />=/.test( data.iFilter ) ? cachedValue >= query : cachedValue > query;
|
2701
|
+
} else if ( /</.test( data.iFilter ) ) {
|
2702
|
+
result = /<=/.test( data.iFilter ) ? cachedValue <= query : cachedValue < query;
|
2703
|
+
}
|
2640
2704
|
// keep showing all rows if nothing follows the operator
|
2641
|
-
if ( !result && savedSearch === '' ) {
|
2705
|
+
if ( !result && savedSearch === '' ) {
|
2706
|
+
result = true;
|
2707
|
+
}
|
2642
2708
|
return result;
|
2643
2709
|
}
|
2644
2710
|
return null;
|
2645
2711
|
},
|
2646
2712
|
// Look for a not match
|
2647
2713
|
notMatch: function( c, data ) {
|
2648
|
-
if ( /^\!/.test(data.iFilter) ) {
|
2714
|
+
if ( /^\!/.test( data.iFilter ) ) {
|
2649
2715
|
var indx,
|
2650
|
-
|
2651
|
-
|
2716
|
+
txt = data.iFilter.replace( '!', '' ),
|
2717
|
+
filter = ts.filter.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
2718
|
+
if ( ts.filter.regex.exact.test( filter ) ) {
|
2652
2719
|
// look for exact not matches - see #628
|
2653
|
-
filter = filter.replace(ts.filter.regex.exact, '');
|
2654
|
-
return filter === '' ? true : $.trim(filter) !== data.iExact;
|
2720
|
+
filter = filter.replace( ts.filter.regex.exact, '' );
|
2721
|
+
return filter === '' ? true : $.trim( filter ) !== data.iExact;
|
2655
2722
|
} else {
|
2656
|
-
indx = data.iExact.search( $.trim(filter) );
|
2657
|
-
return filter === '' ? true : !(c.widgetOptions.filter_startsWith ? indx === 0 : indx >= 0);
|
2723
|
+
indx = data.iExact.search( $.trim( filter ) );
|
2724
|
+
return filter === '' ? true : !( c.widgetOptions.filter_startsWith ? indx === 0 : indx >= 0 );
|
2658
2725
|
}
|
2659
2726
|
}
|
2660
2727
|
return null;
|
@@ -2662,84 +2729,101 @@ ts.filter = {
|
|
2662
2729
|
// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
|
2663
2730
|
exact: function( c, data ) {
|
2664
2731
|
/*jshint eqeqeq:false */
|
2665
|
-
if (ts.filter.regex.exact.test(data.iFilter)) {
|
2666
|
-
var
|
2667
|
-
|
2732
|
+
if ( ts.filter.regex.exact.test( data.iFilter ) ) {
|
2733
|
+
var txt = data.iFilter.replace( ts.filter.regex.exact, '' ),
|
2734
|
+
filter = ts.filter.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
2735
|
+
return data.anyMatch ? $.inArray( filter, data.rowArray ) >= 0 : filter == data.iExact;
|
2668
2736
|
}
|
2669
2737
|
return null;
|
2670
2738
|
},
|
2671
|
-
// Look for an AND or && operator (logical and)
|
2739
|
+
// Look for an AND or && operator ( logical and )
|
2672
2740
|
and : function( c, data ) {
|
2673
|
-
if ( ts.filter.regex.andTest.test(data.filter) ) {
|
2741
|
+
if ( ts.filter.regex.andTest.test( data.filter ) ) {
|
2674
2742
|
var index = data.index,
|
2675
2743
|
parsed = data.parsed[index],
|
2676
2744
|
query = data.iFilter.split( ts.filter.regex.andSplit ),
|
2677
|
-
result = data.iExact.search( $.trim( ts.filter.parseFilter(c, query[0], index, parsed) ) ) >= 0,
|
2745
|
+
result = data.iExact.search( $.trim( ts.filter.parseFilter( c, query[0], index, parsed ) ) ) >= 0,
|
2678
2746
|
indx = query.length - 1;
|
2679
|
-
while (result && indx) {
|
2680
|
-
result = result &&
|
2747
|
+
while ( result && indx ) {
|
2748
|
+
result = result &&
|
2749
|
+
data.iExact.search( $.trim( ts.filter.parseFilter( c, query[indx], index, parsed ) ) ) >= 0;
|
2681
2750
|
indx--;
|
2682
2751
|
}
|
2683
2752
|
return result;
|
2684
2753
|
}
|
2685
2754
|
return null;
|
2686
2755
|
},
|
2687
|
-
// Look for a range (using
|
2756
|
+
// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
|
2688
2757
|
range : function( c, data ) {
|
2689
|
-
if ( ts.filter.regex.toTest.test(data.iFilter) ) {
|
2690
|
-
var result, tmp,
|
2758
|
+
if ( ts.filter.regex.toTest.test( data.iFilter ) ) {
|
2759
|
+
var result, tmp, range1, range2,
|
2691
2760
|
table = c.table,
|
2692
2761
|
index = data.index,
|
2693
2762
|
parsed = data.parsed[index],
|
2694
2763
|
// make sure the dash is for a range and not indicating a negative number
|
2695
|
-
query = data.iFilter.split( ts.filter.regex.toSplit )
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2708
|
-
if (
|
2709
|
-
|
2764
|
+
query = data.iFilter.split( ts.filter.regex.toSplit );
|
2765
|
+
|
2766
|
+
tmp = query[0].replace( ts.filter.regex.nondigit, '' ) || '';
|
2767
|
+
range1 = ts.formatFloat( ts.filter.parseFilter( c, tmp, index, parsed ), table );
|
2768
|
+
tmp = query[1].replace( ts.filter.regex.nondigit, '' ) || '';
|
2769
|
+
range2 = ts.formatFloat( ts.filter.parseFilter( c, tmp, index, parsed ), table );
|
2770
|
+
// parse filter value in case we're comparing numbers ( dates )
|
2771
|
+
if ( parsed || c.parsers[index].type === 'numeric' ) {
|
2772
|
+
result = c.parsers[ index ].format( '' + query[0], table, c.$headers.eq( index ), index );
|
2773
|
+
range1 = ( result !== '' && !isNaN( result ) ) ? result : range1;
|
2774
|
+
result = c.parsers[ index ].format( '' + query[1], table, c.$headers.eq( index ), index );
|
2775
|
+
range2 = ( result !== '' && !isNaN( result ) ) ? result : range2;
|
2776
|
+
}
|
2777
|
+
if ( ( parsed || c.parsers[ index ].type === 'numeric' ) && !isNaN( range1 ) && !isNaN( range2 ) ) {
|
2778
|
+
result = data.cache;
|
2779
|
+
} else {
|
2780
|
+
tmp = isNaN( data.iExact ) ? data.iExact.replace( ts.filter.regex.nondigit, '' ) : data.iExact;
|
2781
|
+
result = ts.formatFloat( tmp, table );
|
2782
|
+
}
|
2783
|
+
if ( range1 > range2 ) {
|
2784
|
+
tmp = range1; range1 = range2; range2 = tmp; // swap
|
2785
|
+
}
|
2786
|
+
return ( result >= range1 && result <= range2 ) || ( range1 === '' || range2 === '' );
|
2710
2787
|
}
|
2711
2788
|
return null;
|
2712
2789
|
},
|
2713
2790
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
2714
2791
|
wild : function( c, data ) {
|
2715
|
-
if ( /[\?\*\|]/.test(data.iFilter) || ts.filter.regex.orReplace.test(data.filter) ) {
|
2792
|
+
if ( /[\?\*\|]/.test( data.iFilter ) || ts.filter.regex.orReplace.test( data.filter ) ) {
|
2716
2793
|
var index = data.index,
|
2717
|
-
parsed = data.parsed[index],
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2794
|
+
parsed = data.parsed[ index ],
|
2795
|
+
txt = data.iFilter.replace( ts.filter.regex.orReplace, '|' ),
|
2796
|
+
query = ts.filter.parseFilter( c, txt, index, parsed ) || '';
|
2797
|
+
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
2798
|
+
if ( !c.$headerIndexed[ index ].hasClass( 'filter-match' ) && /\|/.test( query ) ) {
|
2721
2799
|
// show all results while using filter match. Fixes #727
|
2722
|
-
if (query[ query.length - 1 ] === '|') {
|
2723
|
-
|
2800
|
+
if ( query[ query.length - 1 ] === '|' ) {
|
2801
|
+
query += '*';
|
2802
|
+
}
|
2803
|
+
query = data.anyMatch && $.isArray( data.rowArray ) ?
|
2804
|
+
'(' + query + ')' :
|
2805
|
+
'^(' + query + ')$';
|
2724
2806
|
}
|
2725
2807
|
// parsing the filter may not work properly when using wildcards =/
|
2726
|
-
return new RegExp( query.replace(/\?/g, '\\S{1}').replace(/\*/g, '\\S*') )
|
2808
|
+
return new RegExp( query.replace( /\?/g, '\\S{1}' ).replace( /\*/g, '\\S*' ) )
|
2809
|
+
.test( data.iExact );
|
2727
2810
|
}
|
2728
2811
|
return null;
|
2729
2812
|
},
|
2730
|
-
// fuzzy text search; modified from https://github.com/mattyork/fuzzy (MIT license)
|
2813
|
+
// fuzzy text search; modified from https://github.com/mattyork/fuzzy ( MIT license )
|
2731
2814
|
fuzzy: function( c, data ) {
|
2732
|
-
if ( /^~/.test(data.iFilter) ) {
|
2815
|
+
if ( /^~/.test( data.iFilter ) ) {
|
2733
2816
|
var indx,
|
2734
2817
|
patternIndx = 0,
|
2735
2818
|
len = data.iExact.length,
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2819
|
+
txt = data.iFilter.slice( 1 ),
|
2820
|
+
pattern = ts.filter.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
2821
|
+
for ( indx = 0; indx < len; indx++ ) {
|
2822
|
+
if ( data.iExact[ indx ] === pattern[ patternIndx ] ) {
|
2739
2823
|
patternIndx += 1;
|
2740
2824
|
}
|
2741
2825
|
}
|
2742
|
-
if (patternIndx === pattern.length) {
|
2826
|
+
if ( patternIndx === pattern.length ) {
|
2743
2827
|
return true;
|
2744
2828
|
}
|
2745
2829
|
return false;
|
@@ -2747,17 +2831,17 @@ ts.filter = {
|
|
2747
2831
|
return null;
|
2748
2832
|
}
|
2749
2833
|
},
|
2750
|
-
init: function(table, c, wo) {
|
2834
|
+
init: function( table, c, wo ) {
|
2751
2835
|
// filter language options
|
2752
|
-
ts.language = $.extend(true, {}, {
|
2836
|
+
ts.language = $.extend( true, {}, {
|
2753
2837
|
to : 'to',
|
2754
2838
|
or : 'or',
|
2755
2839
|
and : 'and'
|
2756
|
-
}, ts.language);
|
2840
|
+
}, ts.language );
|
2757
2841
|
|
2758
2842
|
var options, string, txt, $header, column, filters, val, fxn, noSelect,
|
2759
2843
|
regex = ts.filter.regex;
|
2760
|
-
c.$table.addClass('hasFilters');
|
2844
|
+
c.$table.addClass( 'hasFilters' );
|
2761
2845
|
|
2762
2846
|
// define timers so using clearTimeout won't cause an undefined error
|
2763
2847
|
wo.searchTimer = null;
|
@@ -2767,512 +2851,566 @@ ts.filter = {
|
|
2767
2851
|
wo.filter_anyColumnSelector = '[data-column="all"],[data-column="any"]';
|
2768
2852
|
wo.filter_multipleColumnSelector = '[data-column*="-"],[data-column*=","]';
|
2769
2853
|
|
2770
|
-
|
2854
|
+
val = '\\{' + ts.filter.regex.query + '\\}';
|
2771
2855
|
$.extend( regex, {
|
2772
|
-
child : new RegExp(c.cssChildRow),
|
2773
|
-
filtered : new RegExp(wo.filter_filteredRow),
|
2774
|
-
alreadyFiltered : new RegExp('(\\s+(' + ts.language.or + '|-|' + ts.language.to + ')\\s+)', 'i'),
|
2775
|
-
toTest : new RegExp('\\s+(-|' + ts.language.to + ')\\s+', 'i'),
|
2776
|
-
toSplit : new RegExp('(?:\\s+(?:-|' + ts.language.to + ')\\s+)' ,'gi'),
|
2777
|
-
andTest : new RegExp('\\s+(' + ts.language.and + '|&&)\\s+', 'i'),
|
2778
|
-
andSplit : new RegExp('(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi'),
|
2779
|
-
orReplace : new RegExp('\\s+(' + ts.language.or + ')\\s+', 'gi'),
|
2780
|
-
iQuery : new RegExp(
|
2781
|
-
igQuery : new RegExp(
|
2856
|
+
child : new RegExp( c.cssChildRow ),
|
2857
|
+
filtered : new RegExp( wo.filter_filteredRow ),
|
2858
|
+
alreadyFiltered : new RegExp( '(\\s+(' + ts.language.or + '|-|' + ts.language.to + ')\\s+)', 'i' ),
|
2859
|
+
toTest : new RegExp( '\\s+(-|' + ts.language.to + ')\\s+', 'i' ),
|
2860
|
+
toSplit : new RegExp( '(?:\\s+(?:-|' + ts.language.to + ')\\s+)' ,'gi' ),
|
2861
|
+
andTest : new RegExp( '\\s+(' + ts.language.and + '|&&)\\s+', 'i' ),
|
2862
|
+
andSplit : new RegExp( '(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi' ),
|
2863
|
+
orReplace : new RegExp( '\\s+(' + ts.language.or + ')\\s+', 'gi' ),
|
2864
|
+
iQuery : new RegExp( val, 'i' ),
|
2865
|
+
igQuery : new RegExp( val, 'ig' )
|
2782
2866
|
});
|
2783
2867
|
|
2784
|
-
// don't build filter row if columnFilters is false or all columns are set to
|
2785
|
-
|
2868
|
+
// don't build filter row if columnFilters is false or all columns are set to 'filter-false'
|
2869
|
+
// see issue #156
|
2870
|
+
val = c.$headers.filter( '.filter-false, .parser-false' ).length;
|
2871
|
+
if ( wo.filter_columnFilters !== false && val !== c.$headers.length ) {
|
2786
2872
|
// build filter row
|
2787
|
-
ts.filter.buildRow(table, c, wo);
|
2873
|
+
ts.filter.buildRow( table, c, wo );
|
2788
2874
|
}
|
2789
2875
|
|
2790
|
-
txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2876
|
+
txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
|
2877
|
+
.split( ' ' ).join( c.namespace + 'filter ' );
|
2878
|
+
c.$table.bind( txt, function( event, filter ) {
|
2879
|
+
val = wo.filter_hideEmpty &&
|
2880
|
+
$.isEmptyObject( c.cache ) &&
|
2881
|
+
!( c.delayInit && event.type === 'appendCache' );
|
2882
|
+
// hide filter row using the 'filtered' class name
|
2883
|
+
c.$table.find( '.' + tscss.filterRow ).toggleClass( wo.filter_filteredRow, val ); // fixes #450
|
2884
|
+
if ( !/(search|filter)/.test( event.type ) ) {
|
2796
2885
|
event.stopPropagation();
|
2797
|
-
ts.filter.buildDefault(table, true);
|
2886
|
+
ts.filter.buildDefault( table, true );
|
2798
2887
|
}
|
2799
|
-
if (event.type === 'filterReset') {
|
2800
|
-
c.$table.find('.' + tscss.filter).add(wo.filter_$externalFilters).val('');
|
2801
|
-
ts.filter.searching(table, []);
|
2802
|
-
} else if (event.type === 'filterEnd') {
|
2803
|
-
ts.filter.buildDefault(table, true);
|
2888
|
+
if ( event.type === 'filterReset' ) {
|
2889
|
+
c.$table.find( '.' + tscss.filter ).add( wo.filter_$externalFilters ).val( '' );
|
2890
|
+
ts.filter.searching( table, [] );
|
2891
|
+
} else if ( event.type === 'filterEnd' ) {
|
2892
|
+
ts.filter.buildDefault( table, true );
|
2804
2893
|
} else {
|
2805
|
-
// send false argument to force a new search; otherwise if the filter hasn't changed,
|
2806
|
-
|
2807
|
-
|
2894
|
+
// send false argument to force a new search; otherwise if the filter hasn't changed,
|
2895
|
+
// it will return
|
2896
|
+
filter = event.type === 'search' ? filter :
|
2897
|
+
event.type === 'updateComplete' ? c.$table.data( 'lastSearch' ) : '';
|
2898
|
+
if ( /(update|add)/.test( event.type ) && event.type !== 'updateComplete' ) {
|
2808
2899
|
// force a new search since content has changed
|
2809
2900
|
c.lastCombinedFilter = null;
|
2810
2901
|
c.lastSearch = [];
|
2811
2902
|
}
|
2812
|
-
// pass true (skipFirst) to prevent the tablesorter.setFilters function from skipping the first
|
2813
|
-
// ensures all inputs are updated when a search is triggered on the table
|
2814
|
-
|
2903
|
+
// pass true ( skipFirst ) to prevent the tablesorter.setFilters function from skipping the first
|
2904
|
+
// input ensures all inputs are updated when a search is triggered on the table
|
2905
|
+
// $( 'table' ).trigger( 'search', [...] );
|
2906
|
+
ts.filter.searching( table, filter, true );
|
2815
2907
|
}
|
2816
2908
|
return false;
|
2817
2909
|
});
|
2818
2910
|
|
2819
2911
|
// reset button/link
|
2820
|
-
if (wo.filter_reset) {
|
2821
|
-
if (wo.filter_reset instanceof $) {
|
2912
|
+
if ( wo.filter_reset ) {
|
2913
|
+
if ( wo.filter_reset instanceof $ ) {
|
2822
2914
|
// reset contains a jQuery object, bind to it
|
2823
|
-
wo.filter_reset.click(function(){
|
2824
|
-
c.$table.trigger('filterReset');
|
2915
|
+
wo.filter_reset.click( function() {
|
2916
|
+
c.$table.trigger( 'filterReset' );
|
2825
2917
|
});
|
2826
|
-
} else if ($(wo.filter_reset).length) {
|
2918
|
+
} else if ( $( wo.filter_reset ).length ) {
|
2827
2919
|
// reset is a jQuery selector, use event delegation
|
2828
|
-
$(document)
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
2920
|
+
$( document )
|
2921
|
+
.undelegate( wo.filter_reset, 'click.tsfilter' )
|
2922
|
+
.delegate( wo.filter_reset, 'click.tsfilter', function() {
|
2923
|
+
// trigger a reset event, so other functions ( filter_formatter ) know when to reset
|
2924
|
+
c.$table.trigger( 'filterReset' );
|
2925
|
+
});
|
2834
2926
|
}
|
2835
2927
|
}
|
2836
|
-
if (wo.filter_functions) {
|
2837
|
-
for (column = 0; column < c.columns; column++) {
|
2928
|
+
if ( wo.filter_functions ) {
|
2929
|
+
for ( column = 0; column < c.columns; column++ ) {
|
2838
2930
|
fxn = ts.getColumnData( table, wo.filter_functions, column );
|
2839
|
-
if (fxn) {
|
2840
|
-
// remove
|
2841
|
-
|
2842
|
-
|
2843
|
-
|
2931
|
+
if ( fxn ) {
|
2932
|
+
// remove 'filter-select' from header otherwise the options added here are replaced with
|
2933
|
+
// all options
|
2934
|
+
$header = c.$headerIndexed[ column ].removeClass( 'filter-select' );
|
2935
|
+
// don't build select if 'filter-false' or 'parser-false' set
|
2936
|
+
noSelect = !( $header.hasClass( 'filter-false' ) || $header.hasClass( 'parser-false' ) );
|
2844
2937
|
options = '';
|
2845
2938
|
if ( fxn === true && noSelect ) {
|
2846
|
-
ts.filter.buildSelect(table, column);
|
2939
|
+
ts.filter.buildSelect( table, column );
|
2847
2940
|
} else if ( typeof fxn === 'object' && noSelect ) {
|
2848
2941
|
// add custom drop down list
|
2849
|
-
for (string in fxn) {
|
2850
|
-
if (typeof string === 'string') {
|
2942
|
+
for ( string in fxn ) {
|
2943
|
+
if ( typeof string === 'string' ) {
|
2851
2944
|
options += options === '' ?
|
2852
|
-
'<option value="">' +
|
2945
|
+
'<option value="">' +
|
2946
|
+
( $header.data( 'placeholder' ) ||
|
2947
|
+
$header.attr( 'data-placeholder' ) ||
|
2948
|
+
wo.filter_placeholder.select ||
|
2949
|
+
''
|
2950
|
+
) +
|
2951
|
+
'</option>' : '';
|
2853
2952
|
val = string;
|
2854
2953
|
txt = string;
|
2855
|
-
if (string.indexOf(wo.filter_selectSourceSeparator) >= 0) {
|
2856
|
-
val = string.split(wo.filter_selectSourceSeparator);
|
2954
|
+
if ( string.indexOf( wo.filter_selectSourceSeparator ) >= 0 ) {
|
2955
|
+
val = string.split( wo.filter_selectSourceSeparator );
|
2857
2956
|
txt = val[1];
|
2858
2957
|
val = val[0];
|
2859
2958
|
}
|
2860
|
-
options += '<option ' +
|
2959
|
+
options += '<option ' +
|
2960
|
+
( txt === val ? '' : 'data-function-name="' + string + '" ' ) +
|
2961
|
+
'value="' + val + '">' + txt + '</option>';
|
2861
2962
|
}
|
2862
2963
|
}
|
2863
|
-
c.$table
|
2964
|
+
c.$table
|
2965
|
+
.find( 'thead' )
|
2966
|
+
.find( 'select.' + tscss.filter + '[data-column="' + column + '"]' )
|
2967
|
+
.append( options );
|
2864
2968
|
txt = wo.filter_selectSource;
|
2865
|
-
fxn = $.isFunction(txt) ? true : ts.getColumnData( table, txt, column );
|
2866
|
-
if (fxn) {
|
2969
|
+
fxn = $.isFunction( txt ) ? true : ts.getColumnData( table, txt, column );
|
2970
|
+
if ( fxn ) {
|
2867
2971
|
// updating so the extra options are appended
|
2868
|
-
ts.filter.buildSelect(c.table, column, '', true, $header.hasClass(wo.filter_onlyAvail));
|
2972
|
+
ts.filter.buildSelect( c.table, column, '', true, $header.hasClass( wo.filter_onlyAvail ) );
|
2869
2973
|
}
|
2870
2974
|
}
|
2871
2975
|
}
|
2872
2976
|
}
|
2873
2977
|
}
|
2874
|
-
// not really updating, but if the column has both the
|
2875
|
-
// it would append the same options twice.
|
2876
|
-
ts.filter.buildDefault(table, true);
|
2978
|
+
// not really updating, but if the column has both the 'filter-select' class &
|
2979
|
+
// filter_functions set to true, it would append the same options twice.
|
2980
|
+
ts.filter.buildDefault( table, true );
|
2877
2981
|
|
2878
|
-
ts.filter.bindSearch( table, c.$table.find('.' + tscss.filter), true );
|
2879
|
-
if (wo.filter_external) {
|
2982
|
+
ts.filter.bindSearch( table, c.$table.find( '.' + tscss.filter ), true );
|
2983
|
+
if ( wo.filter_external ) {
|
2880
2984
|
ts.filter.bindSearch( table, wo.filter_external );
|
2881
2985
|
}
|
2882
2986
|
|
2883
|
-
if (wo.filter_hideFilters) {
|
2884
|
-
ts.filter.hideFilters(table, c);
|
2987
|
+
if ( wo.filter_hideFilters ) {
|
2988
|
+
ts.filter.hideFilters( table, c );
|
2885
2989
|
}
|
2886
2990
|
|
2887
2991
|
// show processing icon
|
2888
|
-
if (c.showProcessing) {
|
2992
|
+
if ( c.showProcessing ) {
|
2993
|
+
txt = 'filterStart filterEnd '.split( ' ' ).join( c.namespace + 'filter ' );
|
2889
2994
|
c.$table
|
2890
|
-
.unbind(
|
2891
|
-
.bind(
|
2995
|
+
.unbind( txt.replace( /\s+/g, ' ' ) )
|
2996
|
+
.bind( txt, function( event, columns ) {
|
2892
2997
|
// only add processing to certain columns to all columns
|
2893
|
-
$header = (columns) ?
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
2998
|
+
$header = ( columns ) ?
|
2999
|
+
c.$table
|
3000
|
+
.find( '.' + tscss.header )
|
3001
|
+
.filter( '[data-column]' )
|
3002
|
+
.filter( function() {
|
3003
|
+
return columns[ $( this ).data( 'column' ) ] !== '';
|
3004
|
+
}) : '';
|
3005
|
+
ts.isProcessing( table, event.type === 'filterStart', columns ? $header : '' );
|
2897
3006
|
});
|
2898
3007
|
}
|
2899
3008
|
|
2900
|
-
// set filtered rows count (intially unfiltered)
|
3009
|
+
// set filtered rows count ( intially unfiltered )
|
2901
3010
|
c.filteredRows = c.totalRows;
|
2902
3011
|
|
2903
3012
|
// add default values
|
3013
|
+
txt = 'tablesorter-initialized pagerBeforeInitialized '.split( ' ' ).join( c.namespace + 'filter ' );
|
2904
3014
|
c.$table
|
2905
|
-
.unbind(
|
2906
|
-
.bind(
|
2907
|
-
// redefine
|
3015
|
+
.unbind( txt.replace( /\s+/g, ' ' ) )
|
3016
|
+
.bind( txt, function() {
|
3017
|
+
// redefine 'wo' as it does not update properly inside this callback
|
2908
3018
|
var wo = this.config.widgetOptions;
|
2909
|
-
filters = ts.filter.setDefaults(table, c, wo) || [];
|
2910
|
-
if (filters.length) {
|
3019
|
+
filters = ts.filter.setDefaults( table, c, wo ) || [];
|
3020
|
+
if ( filters.length ) {
|
2911
3021
|
// prevent delayInit from triggering a cache build if filters are empty
|
2912
|
-
if ( !(c.delayInit && filters.join('') === '') ) {
|
2913
|
-
ts.setFilters(table, filters, true);
|
3022
|
+
if ( !( c.delayInit && filters.join( '' ) === '' ) ) {
|
3023
|
+
ts.setFilters( table, filters, true );
|
2914
3024
|
}
|
2915
3025
|
}
|
2916
|
-
c.$table.trigger('filterFomatterUpdate');
|
3026
|
+
c.$table.trigger( 'filterFomatterUpdate' );
|
2917
3027
|
// trigger init after setTimeout to prevent multiple filterStart/End/Init triggers
|
2918
|
-
setTimeout(function(){
|
2919
|
-
if (!wo.filter_initialized) {
|
2920
|
-
ts.filter.filterInitComplete(c);
|
3028
|
+
setTimeout( function() {
|
3029
|
+
if ( !wo.filter_initialized ) {
|
3030
|
+
ts.filter.filterInitComplete( c );
|
2921
3031
|
}
|
2922
|
-
}, 100);
|
3032
|
+
}, 100 );
|
2923
3033
|
});
|
2924
3034
|
// if filter widget is added after pager has initialized; then set filter init flag
|
2925
|
-
if (c.pager && c.pager.initialized && !wo.filter_initialized) {
|
2926
|
-
c.$table.trigger('filterFomatterUpdate');
|
2927
|
-
setTimeout(function(){
|
2928
|
-
ts.filter.filterInitComplete(c);
|
2929
|
-
}, 100);
|
3035
|
+
if ( c.pager && c.pager.initialized && !wo.filter_initialized ) {
|
3036
|
+
c.$table.trigger( 'filterFomatterUpdate' );
|
3037
|
+
setTimeout( function() {
|
3038
|
+
ts.filter.filterInitComplete( c );
|
3039
|
+
}, 100 );
|
2930
3040
|
}
|
2931
3041
|
},
|
2932
|
-
// $cell parameter, but not the config, is passed to the
|
2933
|
-
//
|
2934
|
-
formatterUpdated: function($cell, column) {
|
2935
|
-
var wo = $cell.closest('table')[0].config.widgetOptions;
|
2936
|
-
if (!wo.filter_initialized) {
|
3042
|
+
// $cell parameter, but not the config, is passed to the filter_formatters,
|
3043
|
+
// so we have to work with it instead
|
3044
|
+
formatterUpdated: function( $cell, column ) {
|
3045
|
+
var wo = $cell.closest( 'table' )[0].config.widgetOptions;
|
3046
|
+
if ( !wo.filter_initialized ) {
|
2937
3047
|
// add updates by column since this function
|
2938
3048
|
// may be called numerous times before initialization
|
2939
|
-
wo.filter_formatterInit[column] = 1;
|
3049
|
+
wo.filter_formatterInit[ column ] = 1;
|
2940
3050
|
}
|
2941
3051
|
},
|
2942
|
-
filterInitComplete: function(c){
|
3052
|
+
filterInitComplete: function( c ) {
|
2943
3053
|
var indx, len,
|
2944
3054
|
wo = c.widgetOptions,
|
2945
3055
|
count = 0,
|
2946
|
-
completed = function(){
|
3056
|
+
completed = function() {
|
2947
3057
|
wo.filter_initialized = true;
|
2948
|
-
c.$table.trigger('filterInit', c);
|
2949
|
-
ts.filter.findRows(c.table, c.$table.data('lastSearch') || []);
|
3058
|
+
c.$table.trigger( 'filterInit', c );
|
3059
|
+
ts.filter.findRows( c.table, c.$table.data( 'lastSearch' ) || [] );
|
2950
3060
|
};
|
2951
3061
|
if ( $.isEmptyObject( wo.filter_formatter ) ) {
|
2952
3062
|
completed();
|
2953
3063
|
} else {
|
2954
3064
|
len = wo.filter_formatterInit.length;
|
2955
|
-
for (indx = 0; indx < len; indx++) {
|
2956
|
-
if (wo.filter_formatterInit[indx] === 1) {
|
3065
|
+
for ( indx = 0; indx < len; indx++ ) {
|
3066
|
+
if ( wo.filter_formatterInit[ indx ] === 1 ) {
|
2957
3067
|
count++;
|
2958
3068
|
}
|
2959
3069
|
}
|
2960
|
-
clearTimeout(wo.filter_initTimer);
|
2961
|
-
if (!wo.filter_initialized && count === wo.filter_formatterCount) {
|
3070
|
+
clearTimeout( wo.filter_initTimer );
|
3071
|
+
if ( !wo.filter_initialized && count === wo.filter_formatterCount ) {
|
2962
3072
|
// filter widget initialized
|
2963
3073
|
completed();
|
2964
|
-
} else if (!wo.filter_initialized) {
|
3074
|
+
} else if ( !wo.filter_initialized ) {
|
2965
3075
|
// fall back in case a filter_formatter doesn't call
|
2966
|
-
// $.tablesorter.filter.formatterUpdated($cell, column), and the count is off
|
2967
|
-
wo.filter_initTimer = setTimeout(function(){
|
3076
|
+
// $.tablesorter.filter.formatterUpdated( $cell, column ), and the count is off
|
3077
|
+
wo.filter_initTimer = setTimeout( function() {
|
2968
3078
|
completed();
|
2969
|
-
}, 500);
|
3079
|
+
}, 500 );
|
2970
3080
|
}
|
2971
3081
|
}
|
2972
3082
|
},
|
2973
3083
|
|
2974
|
-
setDefaults: function(table, c, wo) {
|
3084
|
+
setDefaults: function( table, c, wo ) {
|
2975
3085
|
var isArray, saved, indx, col, $filters,
|
2976
|
-
// get current (default) filters
|
2977
|
-
filters = ts.getFilters(table) || [];
|
2978
|
-
if (wo.filter_saveFilters && ts.storage) {
|
3086
|
+
// get current ( default ) filters
|
3087
|
+
filters = ts.getFilters( table ) || [];
|
3088
|
+
if ( wo.filter_saveFilters && ts.storage ) {
|
2979
3089
|
saved = ts.storage( table, 'tablesorter-filters' ) || [];
|
2980
|
-
isArray = $.isArray(saved);
|
3090
|
+
isArray = $.isArray( saved );
|
2981
3091
|
// make sure we're not just getting an empty array
|
2982
|
-
if ( !(isArray && saved.join('') === '' || !isArray) ) {
|
3092
|
+
if ( !( isArray && saved.join( '' ) === '' || !isArray ) ) {
|
3093
|
+
filters = saved;
|
3094
|
+
}
|
2983
3095
|
}
|
2984
3096
|
// if no filters saved, then check default settings
|
2985
|
-
if (filters.join('') === '') {
|
3097
|
+
if ( filters.join( '' ) === '' ) {
|
2986
3098
|
// allow adding default setting to external filters
|
2987
|
-
$filters = c.$headers.add( wo.filter_$externalFilters )
|
2988
|
-
|
2989
|
-
|
3099
|
+
$filters = c.$headers.add( wo.filter_$externalFilters )
|
3100
|
+
.filter( '[' + wo.filter_defaultAttrib + ']' );
|
3101
|
+
for ( indx = 0; indx <= c.columns; indx++ ) {
|
3102
|
+
// include data-column='all' external filters
|
2990
3103
|
col = indx === c.columns ? 'all' : indx;
|
2991
|
-
filters[indx] = $filters
|
3104
|
+
filters[indx] = $filters
|
3105
|
+
.filter( '[data-column="' + col + '"]' )
|
3106
|
+
.attr( wo.filter_defaultAttrib ) || filters[indx] || '';
|
2992
3107
|
}
|
2993
3108
|
}
|
2994
|
-
c.$table.data('lastSearch', filters);
|
3109
|
+
c.$table.data( 'lastSearch', filters );
|
2995
3110
|
return filters;
|
2996
3111
|
},
|
2997
|
-
parseFilter: function(c, filter, column, parsed
|
2998
|
-
return
|
2999
|
-
c.parsers[column].format( filter, c.table, [], column ) :
|
3000
|
-
filter;
|
3112
|
+
parseFilter: function( c, filter, column, parsed ) {
|
3113
|
+
return parsed ? c.parsers[column].format( filter, c.table, [], column ) : filter;
|
3001
3114
|
},
|
3002
|
-
buildRow: function(table, c, wo) {
|
3003
|
-
var col, column, $header, buildSelect, disabled, name, ffxn,
|
3115
|
+
buildRow: function( table, c, wo ) {
|
3116
|
+
var col, column, $header, buildSelect, disabled, name, ffxn, tmp,
|
3004
3117
|
// c.columns defined in computeThIndexes()
|
3118
|
+
cellFilter = wo.filter_cellFilter,
|
3005
3119
|
columns = c.columns,
|
3006
|
-
arry = $.isArray(
|
3120
|
+
arry = $.isArray( cellFilter ),
|
3007
3121
|
buildFilter = '<tr role="row" class="' + tscss.filterRow + ' ' + c.cssIgnoreRow + '">';
|
3008
|
-
for (column = 0; column < columns; column++) {
|
3009
|
-
|
3010
|
-
|
3122
|
+
for ( column = 0; column < columns; column++ ) {
|
3123
|
+
buildFilter += '<td';
|
3124
|
+
if ( arry ) {
|
3125
|
+
buildFilter += ( cellFilter[ column ] ? ' class="' + cellFilter[ column ] + '"' : '' );
|
3011
3126
|
} else {
|
3012
|
-
buildFilter +=
|
3127
|
+
buildFilter += ( cellFilter !== '' ? ' class="' + cellFilter + '"' : '' );
|
3013
3128
|
}
|
3129
|
+
buildFilter += '></td>';
|
3014
3130
|
}
|
3015
|
-
c.$filters = $(buildFilter += '</tr>'
|
3131
|
+
c.$filters = $( buildFilter += '</tr>' )
|
3132
|
+
.appendTo( c.$table.children( 'thead' ).eq( 0 ) )
|
3133
|
+
.find( 'td' );
|
3016
3134
|
// build each filter input
|
3017
|
-
for (column = 0; column < columns; column++) {
|
3135
|
+
for ( column = 0; column < columns; column++ ) {
|
3018
3136
|
disabled = false;
|
3019
3137
|
// assuming last cell of a column is the main column
|
3020
|
-
$header = c.$headerIndexed[column];
|
3138
|
+
$header = c.$headerIndexed[ column ];
|
3021
3139
|
ffxn = ts.getColumnData( table, wo.filter_functions, column );
|
3022
|
-
buildSelect = (wo.filter_functions && ffxn && typeof ffxn !==
|
3023
|
-
$header.hasClass('filter-select');
|
3140
|
+
buildSelect = ( wo.filter_functions && ffxn && typeof ffxn !== 'function' ) ||
|
3141
|
+
$header.hasClass( 'filter-select' );
|
3024
3142
|
// get data from jQuery data, metadata, headers option or header class name
|
3025
3143
|
col = ts.getColumnData( table, c.headers, column );
|
3026
|
-
disabled = ts.getData($header[0], col, 'filter') === 'false' ||
|
3144
|
+
disabled = ts.getData( $header[0], col, 'filter' ) === 'false' ||
|
3145
|
+
ts.getData( $header[0], col, 'parser' ) === 'false';
|
3027
3146
|
|
3028
|
-
if (buildSelect) {
|
3029
|
-
buildFilter = $('<select>').appendTo( c.$filters.eq(column) );
|
3147
|
+
if ( buildSelect ) {
|
3148
|
+
buildFilter = $( '<select>' ).appendTo( c.$filters.eq( column ) );
|
3030
3149
|
} else {
|
3031
3150
|
ffxn = ts.getColumnData( table, wo.filter_formatter, column );
|
3032
|
-
if (ffxn) {
|
3151
|
+
if ( ffxn ) {
|
3033
3152
|
wo.filter_formatterCount++;
|
3034
|
-
buildFilter = ffxn( c.$filters.eq(column), column );
|
3153
|
+
buildFilter = ffxn( c.$filters.eq( column ), column );
|
3035
3154
|
// no element returned, so lets go find it
|
3036
|
-
if (buildFilter && buildFilter.length === 0) {
|
3037
|
-
buildFilter = c.$filters.eq(column).children('input');
|
3155
|
+
if ( buildFilter && buildFilter.length === 0 ) {
|
3156
|
+
buildFilter = c.$filters.eq( column ).children( 'input' );
|
3038
3157
|
}
|
3039
3158
|
// element not in DOM, so lets attach it
|
3040
|
-
if ( buildFilter && (buildFilter.parent().length === 0 ||
|
3041
|
-
(buildFilter.parent().length && buildFilter.parent()[0] !== c.$filters[column])) ) {
|
3042
|
-
c.$filters.eq(column).append(buildFilter);
|
3159
|
+
if ( buildFilter && ( buildFilter.parent().length === 0 ||
|
3160
|
+
( buildFilter.parent().length && buildFilter.parent()[0] !== c.$filters[column] ) ) ) {
|
3161
|
+
c.$filters.eq( column ).append( buildFilter );
|
3043
3162
|
}
|
3044
3163
|
} else {
|
3045
|
-
buildFilter = $('<input type="search">').appendTo( c.$filters.eq(column) );
|
3164
|
+
buildFilter = $( '<input type="search">' ).appendTo( c.$filters.eq( column ) );
|
3046
3165
|
}
|
3047
|
-
if (buildFilter) {
|
3048
|
-
|
3166
|
+
if ( buildFilter ) {
|
3167
|
+
tmp = $header.data( 'placeholder' ) ||
|
3168
|
+
$header.attr( 'data-placeholder' ) ||
|
3169
|
+
wo.filter_placeholder.search || '';
|
3170
|
+
buildFilter.attr( 'placeholder', tmp );
|
3049
3171
|
}
|
3050
3172
|
}
|
3051
|
-
if (buildFilter) {
|
3173
|
+
if ( buildFilter ) {
|
3052
3174
|
// add filter class name
|
3053
|
-
name = ( $.isArray(wo.filter_cssFilter) ?
|
3054
|
-
(typeof wo.filter_cssFilter[column] !== 'undefined' ? wo.filter_cssFilter[column] || '' : '') :
|
3175
|
+
name = ( $.isArray( wo.filter_cssFilter ) ?
|
3176
|
+
( typeof wo.filter_cssFilter[column] !== 'undefined' ? wo.filter_cssFilter[column] || '' : '' ) :
|
3055
3177
|
wo.filter_cssFilter ) || '';
|
3056
|
-
buildFilter.addClass( tscss.filter + ' ' + name ).attr('data-column', column);
|
3057
|
-
if (disabled) {
|
3058
|
-
buildFilter.attr('placeholder', '').addClass(tscss.filterDisabled)[0].disabled = true;
|
3178
|
+
buildFilter.addClass( tscss.filter + ' ' + name ).attr( 'data-column', column );
|
3179
|
+
if ( disabled ) {
|
3180
|
+
buildFilter.attr( 'placeholder', '' ).addClass( tscss.filterDisabled )[0].disabled = true;
|
3059
3181
|
}
|
3060
3182
|
}
|
3061
3183
|
}
|
3062
3184
|
},
|
3063
|
-
bindSearch: function(table, $el, internal) {
|
3064
|
-
table = $(table)[0];
|
3065
|
-
$el = $($el); // allow passing a selector string
|
3066
|
-
if (!$el.length) { return; }
|
3067
|
-
var
|
3185
|
+
bindSearch: function( table, $el, internal ) {
|
3186
|
+
table = $( table )[0];
|
3187
|
+
$el = $( $el ); // allow passing a selector string
|
3188
|
+
if ( !$el.length ) { return; }
|
3189
|
+
var tmp,
|
3190
|
+
c = table.config,
|
3068
3191
|
wo = c.widgetOptions,
|
3192
|
+
namespace = c.namespace + 'filter',
|
3069
3193
|
$ext = wo.filter_$externalFilters;
|
3070
|
-
if (internal !== true) {
|
3194
|
+
if ( internal !== true ) {
|
3071
3195
|
// save anyMatch element
|
3072
|
-
|
3073
|
-
|
3196
|
+
tmp = wo.filter_anyColumnSelector + ',' + wo.filter_multipleColumnSelector;
|
3197
|
+
wo.filter_$anyMatch = $el.filter( tmp );
|
3198
|
+
if ( $ext && $ext.length ) {
|
3074
3199
|
wo.filter_$externalFilters = wo.filter_$externalFilters.add( $el );
|
3075
3200
|
} else {
|
3076
3201
|
wo.filter_$externalFilters = $el;
|
3077
3202
|
}
|
3078
|
-
// update values (external filters added after table initialization)
|
3079
|
-
ts.setFilters(table, c.$table.data('lastSearch') || [], internal === false);
|
3203
|
+
// update values ( external filters added after table initialization )
|
3204
|
+
ts.setFilters( table, c.$table.data( 'lastSearch' ) || [], internal === false );
|
3080
3205
|
}
|
3206
|
+
// unbind events
|
3207
|
+
tmp = ( 'keypress keyup search change '.split( ' ' ).join( namespace + ' ' ) );
|
3081
3208
|
$el
|
3082
|
-
// use data attribute instead of jQuery data since the head is cloned without including
|
3083
|
-
|
3084
|
-
.
|
3209
|
+
// use data attribute instead of jQuery data since the head is cloned without including
|
3210
|
+
// the data/binding
|
3211
|
+
.attr( 'data-lastSearchTime', new Date().getTime() )
|
3212
|
+
.unbind( tmp.replace( /\s+/g, ' ' ) )
|
3085
3213
|
// include change for select - fixes #473
|
3086
|
-
.bind('keyup' +
|
3087
|
-
$(this).attr('data-lastSearchTime', new Date().getTime());
|
3214
|
+
.bind( 'keyup' + namespace, function( event ) {
|
3215
|
+
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
|
3088
3216
|
// emulate what webkit does.... escape clears the filter
|
3089
|
-
if (event.which === 27) {
|
3217
|
+
if ( event.which === 27 ) {
|
3090
3218
|
this.value = '';
|
3091
3219
|
// live search
|
3092
3220
|
} else if ( wo.filter_liveSearch === false ) {
|
3093
3221
|
return;
|
3094
|
-
// don't return if the search value is empty (all rows need to be revealed)
|
3222
|
+
// don't return if the search value is empty ( all rows need to be revealed )
|
3095
3223
|
} else if ( this.value !== '' && (
|
3096
3224
|
// liveSearch can contain a min value length; ignore arrow and meta keys, but allow backspace
|
3097
3225
|
( typeof wo.filter_liveSearch === 'number' && this.value.length < wo.filter_liveSearch ) ||
|
3098
3226
|
// let return & backspace continue on, but ignore arrows & non-valid characters
|
3099
|
-
( event.which !== 13 && event.which !== 8 &&
|
3227
|
+
( event.which !== 13 && event.which !== 8 &&
|
3228
|
+
( event.which < 32 || ( event.which >= 37 && event.which <= 40 ) ) ) ) ) {
|
3100
3229
|
return;
|
3101
3230
|
}
|
3102
3231
|
// change event = no delay; last true flag tells getFilters to skip newest timed input
|
3103
3232
|
ts.filter.searching( table, true, true );
|
3104
3233
|
})
|
3105
|
-
.bind( 'search change keypress '.split(' ').join(
|
3106
|
-
var column = $(this).data('column');
|
3107
|
-
// don't allow
|
3108
|
-
if (event.which === 13 || event.type === 'search' ||
|
3234
|
+
.bind( 'search change keypress '.split( ' ' ).join( namespace + ' ' ), function( event ) {
|
3235
|
+
var column = $( this ).data( 'column' );
|
3236
|
+
// don't allow 'change' event to process if the input value is the same - fixes #685
|
3237
|
+
if ( event.which === 13 || event.type === 'search' ||
|
3238
|
+
event.type === 'change' && this.value !== c.lastSearch[column] ) {
|
3109
3239
|
event.preventDefault();
|
3110
3240
|
// init search with no delay
|
3111
|
-
$(this).attr('data-lastSearchTime', new Date().getTime());
|
3241
|
+
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
|
3112
3242
|
ts.filter.searching( table, false, true );
|
3113
3243
|
}
|
3114
3244
|
});
|
3115
3245
|
},
|
3116
|
-
searching: function(table, filter, skipFirst) {
|
3246
|
+
searching: function( table, filter, skipFirst ) {
|
3117
3247
|
var wo = table.config.widgetOptions;
|
3118
|
-
clearTimeout(wo.searchTimer);
|
3119
|
-
if (typeof filter === 'undefined' || filter === true) {
|
3248
|
+
clearTimeout( wo.searchTimer );
|
3249
|
+
if ( typeof filter === 'undefined' || filter === true ) {
|
3120
3250
|
// delay filtering
|
3121
|
-
wo.searchTimer = setTimeout(function() {
|
3122
|
-
ts.filter.checkFilters(table, filter, skipFirst );
|
3123
|
-
}, wo.filter_liveSearch ? wo.filter_searchDelay : 10);
|
3251
|
+
wo.searchTimer = setTimeout( function() {
|
3252
|
+
ts.filter.checkFilters( table, filter, skipFirst );
|
3253
|
+
}, wo.filter_liveSearch ? wo.filter_searchDelay : 10 );
|
3124
3254
|
} else {
|
3125
3255
|
// skip delay
|
3126
|
-
ts.filter.checkFilters(table, filter, skipFirst);
|
3256
|
+
ts.filter.checkFilters( table, filter, skipFirst );
|
3127
3257
|
}
|
3128
3258
|
},
|
3129
|
-
checkFilters: function(table, filter, skipFirst) {
|
3259
|
+
checkFilters: function( table, filter, skipFirst ) {
|
3130
3260
|
var c = table.config,
|
3131
3261
|
wo = c.widgetOptions,
|
3132
|
-
filterArray = $.isArray(filter),
|
3133
|
-
filters = (filterArray) ? filter : ts.getFilters(table, true),
|
3134
|
-
combinedFilters = (filters || []).join(''); // combined filter values
|
3262
|
+
filterArray = $.isArray( filter ),
|
3263
|
+
filters = ( filterArray ) ? filter : ts.getFilters( table, true ),
|
3264
|
+
combinedFilters = ( filters || [] ).join( '' ); // combined filter values
|
3135
3265
|
// prevent errors if delay init is set
|
3136
|
-
if ($.isEmptyObject(c.cache)) {
|
3137
|
-
// update cache if delayInit set & pager has initialized (after user initiates a search)
|
3138
|
-
if (c.delayInit && c.pager && c.pager.initialized) {
|
3139
|
-
c.$table.trigger('updateCache', [function(){
|
3140
|
-
ts.filter.checkFilters(table, false, skipFirst);
|
3141
|
-
}] );
|
3266
|
+
if ( $.isEmptyObject( c.cache ) ) {
|
3267
|
+
// update cache if delayInit set & pager has initialized ( after user initiates a search )
|
3268
|
+
if ( c.delayInit && c.pager && c.pager.initialized ) {
|
3269
|
+
c.$table.trigger( 'updateCache', [ function() {
|
3270
|
+
ts.filter.checkFilters( table, false, skipFirst );
|
3271
|
+
} ] );
|
3142
3272
|
}
|
3143
3273
|
return;
|
3144
3274
|
}
|
3145
3275
|
// add filter array back into inputs
|
3146
|
-
if (filterArray) {
|
3276
|
+
if ( filterArray ) {
|
3147
3277
|
ts.setFilters( table, filters, false, skipFirst !== true );
|
3148
|
-
if (!wo.filter_initialized) { c.lastCombinedFilter = ''; }
|
3278
|
+
if ( !wo.filter_initialized ) { c.lastCombinedFilter = ''; }
|
3149
3279
|
}
|
3150
|
-
if (wo.filter_hideFilters) {
|
3280
|
+
if ( wo.filter_hideFilters ) {
|
3151
3281
|
// show/hide filter row as needed
|
3152
|
-
c.$table
|
3282
|
+
c.$table
|
3283
|
+
.find( '.' + tscss.filterRow )
|
3284
|
+
.trigger( combinedFilters === '' ? 'mouseleave' : 'mouseenter' );
|
3153
3285
|
}
|
3154
3286
|
// return if the last search is the same; but filter === false when updating the search
|
3155
3287
|
// see example-widget-filter.html filter toggle buttons
|
3156
|
-
if (c.lastCombinedFilter === combinedFilters && filter !== false) {
|
3288
|
+
if ( c.lastCombinedFilter === combinedFilters && filter !== false ) {
|
3157
3289
|
return;
|
3158
|
-
} else if (filter === false) {
|
3290
|
+
} else if ( filter === false ) {
|
3159
3291
|
// force filter refresh
|
3160
3292
|
c.lastCombinedFilter = null;
|
3161
3293
|
c.lastSearch = [];
|
3162
3294
|
}
|
3163
|
-
if (wo.filter_initialized) {
|
3164
|
-
|
3295
|
+
if ( wo.filter_initialized ) {
|
3296
|
+
c.$table.trigger( 'filterStart', [filters] );
|
3297
|
+
}
|
3298
|
+
if ( c.showProcessing ) {
|
3165
3299
|
// give it time for the processing icon to kick in
|
3166
|
-
setTimeout(function() {
|
3167
|
-
ts.filter.findRows(table, filters, combinedFilters);
|
3300
|
+
setTimeout( function() {
|
3301
|
+
ts.filter.findRows( table, filters, combinedFilters );
|
3168
3302
|
return false;
|
3169
|
-
}, 30);
|
3303
|
+
}, 30 );
|
3170
3304
|
} else {
|
3171
|
-
ts.filter.findRows(table, filters, combinedFilters);
|
3305
|
+
ts.filter.findRows( table, filters, combinedFilters );
|
3172
3306
|
return false;
|
3173
3307
|
}
|
3174
3308
|
},
|
3175
|
-
hideFilters: function(table, c) {
|
3309
|
+
hideFilters: function( table, c ) {
|
3176
3310
|
var $filterRow, $filterRow2, timer;
|
3177
|
-
$(table)
|
3178
|
-
.find('.' + tscss.filterRow)
|
3179
|
-
.addClass(tscss.filterRowHide)
|
3180
|
-
.bind('mouseenter mouseleave', function(e) {
|
3311
|
+
$( table )
|
3312
|
+
.find( '.' + tscss.filterRow )
|
3313
|
+
.addClass( tscss.filterRowHide )
|
3314
|
+
.bind( 'mouseenter mouseleave', function( e ) {
|
3181
3315
|
// save event object - http://bugs.jquery.com/ticket/12140
|
3182
3316
|
var event = e;
|
3183
|
-
$filterRow = $(this);
|
3184
|
-
clearTimeout(timer);
|
3185
|
-
timer = setTimeout(function() {
|
3186
|
-
if ( /enter|over/.test(event.type) ) {
|
3187
|
-
$filterRow.removeClass(tscss.filterRowHide);
|
3317
|
+
$filterRow = $( this );
|
3318
|
+
clearTimeout( timer );
|
3319
|
+
timer = setTimeout( function() {
|
3320
|
+
if ( /enter|over/.test( event.type ) ) {
|
3321
|
+
$filterRow.removeClass( tscss.filterRowHide );
|
3188
3322
|
} else {
|
3189
3323
|
// don't hide if input has focus
|
3190
|
-
// $(':focus') needs jQuery 1.6+
|
3191
|
-
if ( $(document.activeElement).closest('tr')[0] !== $filterRow[0] ) {
|
3324
|
+
// $( ':focus' ) needs jQuery 1.6+
|
3325
|
+
if ( $( document.activeElement ).closest( 'tr' )[0] !== $filterRow[0] ) {
|
3192
3326
|
// don't hide row if any filter has a value
|
3193
|
-
if (c.lastCombinedFilter === '') {
|
3194
|
-
$filterRow.addClass(tscss.filterRowHide);
|
3327
|
+
if ( c.lastCombinedFilter === '' ) {
|
3328
|
+
$filterRow.addClass( tscss.filterRowHide );
|
3195
3329
|
}
|
3196
3330
|
}
|
3197
3331
|
}
|
3198
|
-
}, 200);
|
3332
|
+
}, 200 );
|
3199
3333
|
})
|
3200
|
-
.find('input, select').bind('focus blur', function(e) {
|
3201
|
-
$filterRow2 = $(this).closest('tr');
|
3202
|
-
clearTimeout(timer);
|
3334
|
+
.find( 'input, select' ).bind( 'focus blur', function( e ) {
|
3335
|
+
$filterRow2 = $( this ).closest( 'tr' );
|
3336
|
+
clearTimeout( timer );
|
3203
3337
|
var event = e;
|
3204
|
-
timer = setTimeout(function() {
|
3338
|
+
timer = setTimeout( function() {
|
3205
3339
|
// don't hide row if any filter has a value
|
3206
|
-
if (ts.getFilters(c.$table).join('') === '') {
|
3207
|
-
$filterRow2
|
3340
|
+
if ( ts.getFilters( c.$table ).join( '' ) === '' ) {
|
3341
|
+
$filterRow2.toggleClass( tscss.filterRowHide, event.type === 'focus' );
|
3208
3342
|
}
|
3209
|
-
}, 200);
|
3343
|
+
}, 200 );
|
3210
3344
|
});
|
3211
3345
|
},
|
3212
|
-
defaultFilter: function(filter, mask){
|
3213
|
-
if (filter === '') { return filter; }
|
3346
|
+
defaultFilter: function( filter, mask ) {
|
3347
|
+
if ( filter === '' ) { return filter; }
|
3214
3348
|
var regex = ts.filter.regex.iQuery,
|
3215
3349
|
maskLen = mask.match( ts.filter.regex.igQuery ).length,
|
3216
|
-
query = maskLen > 1 ? $.trim(filter).split(/\s/) : [ $.trim(filter) ],
|
3350
|
+
query = maskLen > 1 ? $.trim( filter ).split( /\s/ ) : [ $.trim( filter ) ],
|
3217
3351
|
len = query.length - 1,
|
3218
3352
|
indx = 0,
|
3219
3353
|
val = mask;
|
3220
3354
|
if ( len < 1 && maskLen > 1 ) {
|
3221
|
-
// only one
|
3355
|
+
// only one 'word' in query but mask has >1 slots
|
3222
3356
|
query[1] = query[0];
|
3223
3357
|
}
|
3224
3358
|
// replace all {query} with query words...
|
3225
|
-
// if query =
|
3226
|
-
// if query =
|
3227
|
-
while (regex.test(val)) {
|
3228
|
-
val = val.replace(regex, query[indx++] || '');
|
3229
|
-
if (regex.test(val) && indx < len && (query[indx] || '') !== '') {
|
3230
|
-
val = mask.replace(regex, val);
|
3359
|
+
// if query = 'Bob', then convert mask from '!{query}' to '!Bob'
|
3360
|
+
// if query = 'Bob Joe Frank', then convert mask '{q} OR {q}' to 'Bob OR Joe OR Frank'
|
3361
|
+
while ( regex.test( val ) ) {
|
3362
|
+
val = val.replace( regex, query[indx++] || '' );
|
3363
|
+
if ( regex.test( val ) && indx < len && ( query[indx] || '' ) !== '' ) {
|
3364
|
+
val = mask.replace( regex, val );
|
3231
3365
|
}
|
3232
3366
|
}
|
3233
3367
|
return val;
|
3234
3368
|
},
|
3235
3369
|
getLatestSearch: function( $input ) {
|
3236
|
-
if ($input) {
|
3237
|
-
return $input.sort(function(a, b) {
|
3238
|
-
return $(b).attr('data-lastSearchTime') - $(a).attr('data-lastSearchTime');
|
3370
|
+
if ( $input ) {
|
3371
|
+
return $input.sort( function( a, b ) {
|
3372
|
+
return $( b ).attr( 'data-lastSearchTime' ) - $( a ).attr( 'data-lastSearchTime' );
|
3239
3373
|
});
|
3240
3374
|
}
|
3241
3375
|
return $();
|
3242
3376
|
},
|
3243
3377
|
multipleColumns: function( c, $input ) {
|
3244
|
-
// look for multiple columns
|
3378
|
+
// look for multiple columns '1-3,4-6,8' in data-column
|
3245
3379
|
var temp, ranges, range, start, end, singles, i, indx, len,
|
3246
3380
|
wo = c.widgetOptions,
|
3247
|
-
// only target
|
3248
|
-
// & don't target
|
3249
|
-
targets = wo.filter_initialized || !$input.filter(wo.filter_anyColumnSelector).length,
|
3381
|
+
// only target 'all' column inputs on initialization
|
3382
|
+
// & don't target 'all' column inputs if they don't exist
|
3383
|
+
targets = wo.filter_initialized || !$input.filter( wo.filter_anyColumnSelector ).length,
|
3250
3384
|
columns = [],
|
3251
|
-
val = $.trim( ts.filter.getLatestSearch( $input ).attr('data-column') || '' );
|
3385
|
+
val = $.trim( ts.filter.getLatestSearch( $input ).attr( 'data-column' ) || '' );
|
3252
3386
|
// process column range
|
3253
3387
|
if ( targets && /-/.test( val ) ) {
|
3254
3388
|
ranges = val.match( /(\d+)\s*-\s*(\d+)/g );
|
3255
3389
|
len = ranges.length;
|
3256
|
-
for (indx = 0; indx < len; indx++) {
|
3390
|
+
for ( indx = 0; indx < len; indx++ ) {
|
3257
3391
|
range = ranges[indx].split( /\s*-\s*/ );
|
3258
3392
|
start = parseInt( range[0], 10 ) || 0;
|
3259
3393
|
end = parseInt( range[1], 10 ) || ( c.columns - 1 );
|
3260
|
-
if ( start > end ) {
|
3261
|
-
|
3394
|
+
if ( start > end ) {
|
3395
|
+
temp = start; start = end; end = temp; // swap
|
3396
|
+
}
|
3397
|
+
if ( end >= c.columns ) {
|
3398
|
+
end = c.columns - 1;
|
3399
|
+
}
|
3262
3400
|
for ( ; start <= end; start++ ) {
|
3263
|
-
columns.push(start);
|
3401
|
+
columns.push( start );
|
3264
3402
|
}
|
3265
3403
|
// remove processed range from val
|
3266
|
-
val = val.replace( ranges[indx], '' );
|
3404
|
+
val = val.replace( ranges[ indx ], '' );
|
3267
3405
|
}
|
3268
3406
|
}
|
3269
3407
|
// process single columns
|
3270
3408
|
if ( targets && /,/.test( val ) ) {
|
3271
3409
|
singles = val.split( /\s*,\s*/ );
|
3272
3410
|
len = singles.length;
|
3273
|
-
for (i = 0; i < len; i++) {
|
3274
|
-
if (singles[i] !== '') {
|
3275
|
-
indx = parseInt( singles[i], 10 );
|
3411
|
+
for ( i = 0; i < len; i++ ) {
|
3412
|
+
if ( singles[ i ] !== '' ) {
|
3413
|
+
indx = parseInt( singles[ i ], 10 );
|
3276
3414
|
if ( indx < c.columns ) {
|
3277
3415
|
columns.push( indx );
|
3278
3416
|
}
|
@@ -3280,382 +3418,472 @@ ts.filter = {
|
|
3280
3418
|
}
|
3281
3419
|
}
|
3282
3420
|
// return all columns
|
3283
|
-
if (!columns.length) {
|
3421
|
+
if ( !columns.length ) {
|
3284
3422
|
for ( indx = 0; indx < c.columns; indx++ ) {
|
3285
3423
|
columns.push( indx );
|
3286
3424
|
}
|
3287
3425
|
}
|
3288
3426
|
return columns;
|
3289
3427
|
},
|
3290
|
-
|
3291
|
-
|
3292
|
-
|
3293
|
-
|
3294
|
-
|
3295
|
-
|
3428
|
+
processRow: function( c, data, vars ) {
|
3429
|
+
var $cell, columnIndex, hasSelect, matches, result, val, filterMatched, excludeMatch,
|
3430
|
+
fxn, ffxn, txt,
|
3431
|
+
regex = ts.filter.regex,
|
3432
|
+
wo = c.widgetOptions,
|
3433
|
+
showRow = true;
|
3434
|
+
data.$cells = data.$row.children();
|
3435
|
+
|
3436
|
+
if ( data.anyMatchFlag ) {
|
3437
|
+
// look for multiple columns '1-3,4-6,8'
|
3438
|
+
columnIndex = ts.filter.multipleColumns( c, wo.filter_$anyMatch );
|
3439
|
+
data.anyMatch = true;
|
3440
|
+
data.rowArray = data.$cells.map( function( i ) {
|
3441
|
+
if ( $.inArray( i, columnIndex ) > -1 ) {
|
3442
|
+
if ( data.parsed[ i ] ) {
|
3443
|
+
txt = data.cacheArray[ i ];
|
3444
|
+
} else {
|
3445
|
+
txt = data.rawArray[ i ];
|
3446
|
+
txt = $.trim( wo.filter_ignoreCase ? txt.toLowerCase() : txt );
|
3447
|
+
if ( c.sortLocaleCompare ) {
|
3448
|
+
txt = ts.replaceAccents( txt );
|
3449
|
+
}
|
3450
|
+
}
|
3451
|
+
return txt;
|
3452
|
+
}
|
3453
|
+
}).get();
|
3454
|
+
data.filter = data.anyMatchFilter;
|
3455
|
+
data.iFilter = data.iAnyMatchFilter;
|
3456
|
+
data.exact = data.rowArray.join( ' ' );
|
3457
|
+
data.iExact = wo.filter_ignoreCase ? data.exact.toLowerCase() : data.exact;
|
3458
|
+
data.cache = data.cacheArray.slice( 0, -1 ).join( ' ' );
|
3459
|
+
filterMatched = null;
|
3460
|
+
matches = null;
|
3461
|
+
for ( ffxn in ts.filter.types ) {
|
3462
|
+
if ( $.inArray( ffxn, vars.noAnyMatch ) < 0 && matches === null ) {
|
3463
|
+
matches = ts.filter.types[ffxn]( c, data );
|
3464
|
+
if ( matches !== null ) {
|
3465
|
+
filterMatched = matches;
|
3466
|
+
}
|
3467
|
+
}
|
3468
|
+
}
|
3469
|
+
if ( filterMatched !== null ) {
|
3470
|
+
showRow = filterMatched;
|
3471
|
+
} else {
|
3472
|
+
if ( wo.filter_startsWith ) {
|
3473
|
+
showRow = false;
|
3474
|
+
columnIndex = c.columns;
|
3475
|
+
while ( !showRow && columnIndex > 0 ) {
|
3476
|
+
columnIndex--;
|
3477
|
+
showRow = showRow || data.rowArray[ columnIndex ].indexOf( data.iFilter ) === 0;
|
3478
|
+
}
|
3479
|
+
} else {
|
3480
|
+
showRow = ( data.iExact + data.childRowText ).indexOf( data.iFilter ) >= 0;
|
3481
|
+
}
|
3482
|
+
}
|
3483
|
+
data.anyMatch = false;
|
3484
|
+
// no other filters to process
|
3485
|
+
if ( data.filters.join( '' ) === data.filter ) {
|
3486
|
+
return showRow;
|
3487
|
+
}
|
3488
|
+
}
|
3489
|
+
|
3490
|
+
for ( columnIndex = 0; columnIndex < c.columns; columnIndex++ ) {
|
3491
|
+
data.filter = data.filters[ columnIndex ];
|
3492
|
+
data.index = columnIndex;
|
3493
|
+
|
3494
|
+
// filter types to exclude, per column
|
3495
|
+
excludeMatch = vars.excludeFilter[ columnIndex ];
|
3496
|
+
|
3497
|
+
// ignore if filter is empty or disabled
|
3498
|
+
if ( data.filter ) {
|
3499
|
+
data.cache = data.cacheArray[ columnIndex ];
|
3500
|
+
// check if column data should be from the cell or from parsed data
|
3501
|
+
if ( wo.filter_useParsedData || data.parsed[ columnIndex ] ) {
|
3502
|
+
data.exact = data.cache;
|
3503
|
+
} else {
|
3504
|
+
result = data.rawArray[ columnIndex ] || '';
|
3505
|
+
data.exact = c.sortLocaleCompare ? ts.replaceAccents( result ) : result; // issue #405
|
3506
|
+
}
|
3507
|
+
data.iExact = !regex.type.test( typeof data.exact ) && wo.filter_ignoreCase ?
|
3508
|
+
data.exact.toLowerCase() : data.exact;
|
3509
|
+
result = showRow; // if showRow is true, show that row
|
3510
|
+
|
3511
|
+
// in case select filter option has a different value vs text 'a - z|A through Z'
|
3512
|
+
ffxn = wo.filter_columnFilters ?
|
3513
|
+
c.$filters.add( c.$externalFilters )
|
3514
|
+
.filter( '[data-column="'+ columnIndex + '"]' )
|
3515
|
+
.find( 'select option:selected' )
|
3516
|
+
.attr( 'data-function-name' ) || '' : '';
|
3517
|
+
// replace accents - see #357
|
3518
|
+
if ( c.sortLocaleCompare ) {
|
3519
|
+
data.filter = ts.replaceAccents( data.filter );
|
3520
|
+
}
|
3521
|
+
|
3522
|
+
val = true;
|
3523
|
+
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
3524
|
+
data.filter = ts.filter.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
3525
|
+
// val is used to indicate that a filter select is using a default filter;
|
3526
|
+
// so we override the exact & partial matches
|
3527
|
+
val = false;
|
3528
|
+
}
|
3529
|
+
// data.iFilter = case insensitive ( if wo.filter_ignoreCase is true ),
|
3530
|
+
// data.filter = case sensitive
|
3531
|
+
data.iFilter = wo.filter_ignoreCase ? ( data.filter || '' ).toLowerCase() : data.filter;
|
3532
|
+
fxn = vars.functions[ columnIndex ];
|
3533
|
+
$cell = c.$headerIndexed[ columnIndex ];
|
3534
|
+
hasSelect = $cell.hasClass( 'filter-select' );
|
3535
|
+
filterMatched = null;
|
3536
|
+
if ( fxn || ( hasSelect && val ) ) {
|
3537
|
+
if ( fxn === true || hasSelect ) {
|
3538
|
+
// default selector uses exact match unless 'filter-match' class is found
|
3539
|
+
filterMatched = $cell.hasClass( 'filter-match' ) ?
|
3540
|
+
data.iExact.search( data.iFilter ) >= 0 :
|
3541
|
+
data.filter === data.exact;
|
3542
|
+
} else if ( typeof fxn === 'function' ) {
|
3543
|
+
// filter callback( exact cell content, parser normalized content,
|
3544
|
+
// filter input value, column index, jQuery row object )
|
3545
|
+
filterMatched = fxn( data.exact, data.cache, data.filter, columnIndex, data.$row, c, data );
|
3546
|
+
} else if ( typeof fxn[ ffxn || data.filter ] === 'function' ) {
|
3547
|
+
// selector option function
|
3548
|
+
txt = ffxn || data.filter;
|
3549
|
+
filterMatched =
|
3550
|
+
fxn[ txt ]( data.exact, data.cache, data.filter, columnIndex, data.$row, c, data );
|
3551
|
+
}
|
3552
|
+
}
|
3553
|
+
if ( filterMatched === null ) {
|
3554
|
+
// cycle through the different filters
|
3555
|
+
// filters return a boolean or null if nothing matches
|
3556
|
+
matches = null;
|
3557
|
+
for ( ffxn in ts.filter.types ) {
|
3558
|
+
if ( $.inArray( ffxn, excludeMatch ) < 0 && matches === null ) {
|
3559
|
+
matches = ts.filter.types[ ffxn ]( c, data );
|
3560
|
+
if ( matches !== null ) {
|
3561
|
+
filterMatched = matches;
|
3562
|
+
}
|
3563
|
+
}
|
3564
|
+
}
|
3565
|
+
if ( filterMatched !== null ) {
|
3566
|
+
result = filterMatched;
|
3567
|
+
// Look for match, and add child row data for matching
|
3568
|
+
} else {
|
3569
|
+
txt = ( data.iExact + data.childRowText )
|
3570
|
+
.indexOf( ts.filter.parseFilter( c, data.iFilter, columnIndex, data.parsed[ columnIndex ] ) );
|
3571
|
+
result = ( ( !wo.filter_startsWith && txt >= 0 ) || ( wo.filter_startsWith && txt === 0 ) );
|
3572
|
+
}
|
3573
|
+
} else {
|
3574
|
+
result = filterMatched;
|
3575
|
+
}
|
3576
|
+
showRow = ( result ) ? showRow : false;
|
3577
|
+
}
|
3578
|
+
}
|
3579
|
+
return showRow;
|
3580
|
+
},
|
3581
|
+
findRows: function( table, filters, combinedFilters ) {
|
3582
|
+
if ( table.config.lastCombinedFilter === combinedFilters ||
|
3583
|
+
!table.config.widgetOptions.filter_initialized ) {
|
3584
|
+
return;
|
3585
|
+
}
|
3586
|
+
var len, norm_rows, rowData, $rows, rowIndex, tbodyIndex, $tbody, columnIndex,
|
3587
|
+
isChild, childRow, lastSearch, showRow, time, val, indx,
|
3588
|
+
notFiltered, searchFiltered, query, injected, res, id, txt,
|
3589
|
+
storedFilters = $.extend( [], filters ),
|
3296
3590
|
regex = ts.filter.regex,
|
3297
3591
|
c = table.config,
|
3298
3592
|
wo = c.widgetOptions,
|
3299
3593
|
// data object passed to filters; anyMatch is a flag for the filters
|
3300
|
-
data = {
|
3301
|
-
|
3302
|
-
|
3594
|
+
data = {
|
3595
|
+
anyMatch: false,
|
3596
|
+
filters: filters,
|
3597
|
+
// regex filter type cache
|
3598
|
+
filter_regexCache : [],
|
3599
|
+
},
|
3600
|
+
vars = {
|
3601
|
+
// anyMatch really screws up with these types of filters
|
3602
|
+
noAnyMatch: [ 'range', 'notMatch', 'operators' ],
|
3603
|
+
// cache filter variables that use ts.getColumnData in the main loop
|
3604
|
+
functions : [],
|
3605
|
+
excludeFilter : [],
|
3606
|
+
defaultColFilter : [],
|
3607
|
+
defaultAnyFilter : ts.getColumnData( table, wo.filter_defaultFilter, c.columns, true ) || ''
|
3608
|
+
};
|
3303
3609
|
|
3304
3610
|
// parse columns after formatter, in case the class is added at that point
|
3305
|
-
data.parsed = c.$headers.map(function(columnIndex) {
|
3306
|
-
return c.parsers && c.parsers[columnIndex] &&
|
3307
|
-
//
|
3308
|
-
|
3309
|
-
|
3611
|
+
data.parsed = c.$headers.map( function( columnIndex ) {
|
3612
|
+
return c.parsers && c.parsers[ columnIndex ] &&
|
3613
|
+
// force parsing if parser type is numeric
|
3614
|
+
( c.parsers[ columnIndex ].parsed || c.parsers[ columnIndex ].type === 'numeric' ) ||
|
3615
|
+
// getData won't return 'parsed' if other 'filter-' class names exist
|
3616
|
+
// ( e.g. <th class="filter-select filter-parsed"> )
|
3617
|
+
ts.getData && ts.getData( c.$headerIndexed[ columnIndex ],
|
3618
|
+
ts.getColumnData( table, c.headers, columnIndex ), 'filter' ) === 'parsed' ||
|
3619
|
+
$( this ).hasClass( 'filter-parsed' );
|
3310
3620
|
}).get();
|
3311
3621
|
|
3312
|
-
// cache filter variables that use ts.getColumnData in the main loop
|
3313
|
-
wo.filter_indexed = {
|
3314
|
-
functions : [],
|
3315
|
-
excludeFilter : [],
|
3316
|
-
defaultColFilter : [],
|
3317
|
-
defaultAnyFilter : ts.getColumnData( table, wo.filter_defaultFilter, c.columns, true ) || ''
|
3318
|
-
};
|
3319
3622
|
for ( columnIndex = 0; columnIndex < c.columns; columnIndex++ ) {
|
3320
|
-
|
3321
|
-
|
3322
|
-
|
3623
|
+
vars.functions[ columnIndex ] =
|
3624
|
+
ts.getColumnData( table, wo.filter_functions, columnIndex );
|
3625
|
+
vars.defaultColFilter[ columnIndex ] =
|
3626
|
+
ts.getColumnData( table, wo.filter_defaultFilter, columnIndex ) || '';
|
3627
|
+
vars.excludeFilter[ columnIndex ] =
|
3628
|
+
( ts.getColumnData( table, wo.filter_excludeFilter, columnIndex, true ) || '' ).split( /\s+/ );
|
3323
3629
|
}
|
3324
3630
|
|
3325
|
-
if (c.debug) {
|
3326
|
-
ts.log('Filter: Starting filter widget search', filters);
|
3631
|
+
if ( c.debug ) {
|
3632
|
+
ts.log( 'Filter: Starting filter widget search', filters );
|
3327
3633
|
time = new Date();
|
3328
3634
|
}
|
3329
3635
|
// filtered rows count
|
3330
3636
|
c.filteredRows = 0;
|
3331
3637
|
c.totalRows = 0;
|
3332
3638
|
// combindedFilters are undefined on init
|
3333
|
-
combinedFilters = (
|
3639
|
+
combinedFilters = ( storedFilters || [] ).join( '' );
|
3334
3640
|
|
3335
|
-
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
|
3336
|
-
$tbody = ts.processTbody(table, c.$tbodies.eq(tbodyIndex), true);
|
3337
|
-
// skip child rows & widget added (removable) rows - fixes #448 thanks to @hempel!
|
3338
|
-
// $rows = $tbody.children('tr').not(c.selectorRemove);
|
3641
|
+
for ( tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
|
3642
|
+
$tbody = ts.processTbody( table, c.$tbodies.eq( tbodyIndex ), true );
|
3643
|
+
// skip child rows & widget added ( removable ) rows - fixes #448 thanks to @hempel!
|
3644
|
+
// $rows = $tbody.children( 'tr' ).not( c.selectorRemove );
|
3339
3645
|
columnIndex = c.columns;
|
3340
3646
|
// convert stored rows into a jQuery object
|
3341
|
-
norm_rows = c.cache[tbodyIndex].normalized;
|
3342
|
-
$rows = $( $.map(norm_rows, function(
|
3343
|
-
|
3344
|
-
|
3345
|
-
|
3647
|
+
norm_rows = c.cache[ tbodyIndex ].normalized;
|
3648
|
+
$rows = $( $.map( norm_rows, function( el ) {
|
3649
|
+
return el[ columnIndex ].$row.get();
|
3650
|
+
}) );
|
3651
|
+
|
3652
|
+
if ( combinedFilters === '' || wo.filter_serversideFiltering ) {
|
3653
|
+
$rows
|
3654
|
+
.removeClass( wo.filter_filteredRow )
|
3655
|
+
.not( '.' + c.cssChildRow )
|
3656
|
+
.css( 'display', '' );
|
3346
3657
|
} else {
|
3347
3658
|
// filter out child rows
|
3348
|
-
$rows = $rows.not('.' + c.cssChildRow);
|
3659
|
+
$rows = $rows.not( '.' + c.cssChildRow );
|
3349
3660
|
len = $rows.length;
|
3350
3661
|
|
3351
|
-
if ( (wo.filter_$anyMatch && wo.filter_$anyMatch.length) ||
|
3662
|
+
if ( ( wo.filter_$anyMatch && wo.filter_$anyMatch.length ) ||
|
3663
|
+
typeof filters[c.columns] !== 'undefined' ) {
|
3352
3664
|
data.anyMatchFlag = true;
|
3353
|
-
data.anyMatchFilter =
|
3354
|
-
|
3665
|
+
data.anyMatchFilter = '' + (
|
3666
|
+
filters[ c.columns ] ||
|
3667
|
+
wo.filter_$anyMatch && ts.filter.getLatestSearch( wo.filter_$anyMatch ).val() ||
|
3668
|
+
''
|
3669
|
+
);
|
3670
|
+
if ( wo.filter_columnAnyMatch ) {
|
3355
3671
|
// specific columns search
|
3356
|
-
query = data.anyMatchFilter.split(
|
3672
|
+
query = data.anyMatchFilter.split( regex.andSplit );
|
3357
3673
|
injected = false;
|
3358
|
-
for (indx = 0; indx < query.length; indx++) {
|
3359
|
-
res = query[indx].split(':');
|
3674
|
+
for ( indx = 0; indx < query.length; indx++ ) {
|
3675
|
+
res = query[ indx ].split( ':' );
|
3360
3676
|
if ( res.length > 1 ) {
|
3361
3677
|
// make the column a one-based index ( non-developers start counting from one :P )
|
3362
3678
|
id = parseInt( res[0], 10 ) - 1;
|
3363
3679
|
if ( id >= 0 && id < c.columns ) { // if id is an integer
|
3364
|
-
filters[id] = res[1];
|
3365
|
-
query.splice(indx, 1);
|
3680
|
+
filters[ id ] = res[1];
|
3681
|
+
query.splice( indx, 1 );
|
3366
3682
|
indx--;
|
3367
3683
|
injected = true;
|
3368
3684
|
}
|
3369
3685
|
}
|
3370
3686
|
}
|
3371
|
-
if (injected) {
|
3372
|
-
data.anyMatchFilter = query.join(' && ');
|
3687
|
+
if ( injected ) {
|
3688
|
+
data.anyMatchFilter = query.join( ' && ' );
|
3373
3689
|
}
|
3374
3690
|
}
|
3375
3691
|
}
|
3376
3692
|
|
3377
3693
|
// optimize searching only through already filtered rows - see #313
|
3378
3694
|
searchFiltered = wo.filter_searchFiltered;
|
3379
|
-
lastSearch = c.lastSearch || c.$table.data('lastSearch') || [];
|
3380
|
-
if (searchFiltered) {
|
3381
|
-
// cycle through all filters; include last (columnIndex + 1 = match any column). Fixes #669
|
3382
|
-
for (indx = 0; indx < columnIndex + 1; indx++) {
|
3695
|
+
lastSearch = c.lastSearch || c.$table.data( 'lastSearch' ) || [];
|
3696
|
+
if ( searchFiltered ) {
|
3697
|
+
// cycle through all filters; include last ( columnIndex + 1 = match any column ). Fixes #669
|
3698
|
+
for ( indx = 0; indx < columnIndex + 1; indx++ ) {
|
3383
3699
|
val = filters[indx] || '';
|
3384
3700
|
// break out of loop if we've already determined not to search filtered rows
|
3385
|
-
if (!searchFiltered) { indx = columnIndex; }
|
3701
|
+
if ( !searchFiltered ) { indx = columnIndex; }
|
3386
3702
|
// search already filtered rows if...
|
3387
3703
|
searchFiltered = searchFiltered && lastSearch.length &&
|
3388
3704
|
// there are no changes from beginning of filter
|
3389
|
-
val.indexOf(lastSearch[indx] || '') === 0 &&
|
3390
|
-
// if there is NOT a logical
|
3391
|
-
!regex.alreadyFiltered.test(val) &&
|
3392
|
-
// if we are not doing exact matches, using
|
3393
|
-
!/[=\"\|!]/.test(val) &&
|
3394
|
-
// don't search only filtered if the value is negative
|
3395
|
-
|
3396
|
-
|
3397
|
-
|
3705
|
+
val.indexOf( lastSearch[indx] || '' ) === 0 &&
|
3706
|
+
// if there is NOT a logical 'or', or range ( 'to' or '-' ) in the string
|
3707
|
+
!regex.alreadyFiltered.test( val ) &&
|
3708
|
+
// if we are not doing exact matches, using '|' ( logical or ) or not '!'
|
3709
|
+
!/[=\"\|!]/.test( val ) &&
|
3710
|
+
// don't search only filtered if the value is negative
|
3711
|
+
// ( '> -10' => '> -100' will ignore hidden rows )
|
3712
|
+
!( /(>=?\s*-\d)/.test( val ) || /(<=?\s*\d)/.test( val ) ) &&
|
3713
|
+
// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
|
3714
|
+
!( val !== '' && c.$filters && c.$filters.eq( indx ).find( 'select' ).length &&
|
3715
|
+
!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
|
3398
3716
|
}
|
3399
3717
|
}
|
3400
|
-
notFiltered = $rows.not('.' + wo.filter_filteredRow).length;
|
3718
|
+
notFiltered = $rows.not( '.' + wo.filter_filteredRow ).length;
|
3401
3719
|
// can't search when all rows are hidden - this happens when looking for exact matches
|
3402
|
-
if (searchFiltered && notFiltered === 0) { searchFiltered = false; }
|
3403
|
-
if (c.debug) {
|
3404
|
-
ts.log( 'Filter: Searching through ' +
|
3720
|
+
if ( searchFiltered && notFiltered === 0 ) { searchFiltered = false; }
|
3721
|
+
if ( c.debug ) {
|
3722
|
+
ts.log( 'Filter: Searching through ' +
|
3723
|
+
( searchFiltered && notFiltered < len ? notFiltered : 'all' ) + ' rows' );
|
3405
3724
|
}
|
3406
|
-
if (data.anyMatchFlag) {
|
3407
|
-
if (c.sortLocaleCompare) {
|
3725
|
+
if ( data.anyMatchFlag ) {
|
3726
|
+
if ( c.sortLocaleCompare ) {
|
3408
3727
|
// replace accents
|
3409
|
-
data.anyMatchFilter = ts.replaceAccents(data.anyMatchFilter);
|
3728
|
+
data.anyMatchFilter = ts.replaceAccents( data.anyMatchFilter );
|
3410
3729
|
}
|
3411
|
-
if ( wo.filter_defaultFilter && regex.iQuery.test(
|
3412
|
-
data.anyMatchFilter = ts.filter.defaultFilter( data.anyMatchFilter,
|
3730
|
+
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultAnyFilter ) ) {
|
3731
|
+
data.anyMatchFilter = ts.filter.defaultFilter( data.anyMatchFilter, vars.defaultAnyFilter );
|
3413
3732
|
// clear search filtered flag because default filters are not saved to the last search
|
3414
3733
|
searchFiltered = false;
|
3415
3734
|
}
|
3416
3735
|
// make iAnyMatchFilter lowercase unless both filter widget & core ignoreCase options are true
|
3417
3736
|
// when c.ignoreCase is true, the cache contains all lower case data
|
3418
|
-
data.iAnyMatchFilter = !(wo.filter_ignoreCase && c.ignoreCase) ?
|
3737
|
+
data.iAnyMatchFilter = !( wo.filter_ignoreCase && c.ignoreCase ) ?
|
3738
|
+
data.anyMatchFilter :
|
3739
|
+
data.anyMatchFilter.toLowerCase();
|
3419
3740
|
}
|
3420
3741
|
|
3421
3742
|
// loop through the rows
|
3422
|
-
for (rowIndex = 0; rowIndex < len; rowIndex++) {
|
3743
|
+
for ( rowIndex = 0; rowIndex < len; rowIndex++ ) {
|
3423
3744
|
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3745
|
+
txt = $rows[ rowIndex ].className;
|
3746
|
+
// the first row can never be a child row
|
3747
|
+
isChild = rowIndex && regex.child.test( txt );
|
3427
3748
|
// skip child rows & already filtered rows
|
3428
|
-
if (
|
3429
|
-
|
3430
|
-
// *** nextAll/nextUntil not supported by Zepto! ***
|
3431
|
-
childRow = $rows.eq(rowIndex).nextUntil('tr:not(.' + c.cssChildRow + ')');
|
3432
|
-
// so, if "table.config.widgetOptions.filter_childRows" is true and there is
|
3433
|
-
// a match anywhere in the child row, then it will make the row visible
|
3434
|
-
// checked here so the option can be changed dynamically
|
3435
|
-
data.childRowText = (childRow.length && wo.filter_childRows) ? childRow.text() : '';
|
3436
|
-
data.childRowText = wo.filter_ignoreCase ? data.childRowText.toLocaleLowerCase() : data.childRowText;
|
3437
|
-
$cells = $rows.eq(rowIndex).children();
|
3438
|
-
if (data.anyMatchFlag) {
|
3439
|
-
// look for multiple columns "1-3,4-6,8"
|
3440
|
-
columnIndex = ts.filter.multipleColumns( c, wo.filter_$anyMatch );
|
3441
|
-
data.anyMatch = true;
|
3442
|
-
data.rowArray = $cells.map(function(i){
|
3443
|
-
if ( $.inArray(i, columnIndex) > -1 ) {
|
3444
|
-
var txt;
|
3445
|
-
if (data.parsed[i]) {
|
3446
|
-
txt = data.cacheArray[i];
|
3447
|
-
} else {
|
3448
|
-
txt = this ? this.getAttribute( c.textAttribute ) || this.textContent || $(this).text() : '';
|
3449
|
-
txt = $.trim( wo.filter_ignoreCase ? txt.toLowerCase() : txt );
|
3450
|
-
if (c.sortLocaleCompare) {
|
3451
|
-
txt = ts.replaceAccents(txt);
|
3452
|
-
}
|
3453
|
-
}
|
3454
|
-
return txt;
|
3455
|
-
}
|
3456
|
-
}).get();
|
3457
|
-
data.filter = data.anyMatchFilter;
|
3458
|
-
data.iFilter = data.iAnyMatchFilter;
|
3459
|
-
data.exact = data.rowArray.join(' ');
|
3460
|
-
data.iExact = wo.filter_ignoreCase ? data.exact.toLowerCase() : data.exact;
|
3461
|
-
data.cache = data.cacheArray.slice(0,-1).join(' ');
|
3462
|
-
filterMatched = null;
|
3463
|
-
$.each(ts.filter.types, function(type, typeFunction) {
|
3464
|
-
if ($.inArray(type, noAnyMatch) < 0) {
|
3465
|
-
matches = typeFunction( c, data );
|
3466
|
-
if (matches !== null) {
|
3467
|
-
filterMatched = matches;
|
3468
|
-
return false;
|
3469
|
-
}
|
3470
|
-
}
|
3471
|
-
});
|
3472
|
-
if (filterMatched !== null) {
|
3473
|
-
showRow = filterMatched;
|
3474
|
-
} else {
|
3475
|
-
if (wo.filter_startsWith) {
|
3476
|
-
showRow = false;
|
3477
|
-
columnIndex = c.columns;
|
3478
|
-
while (!showRow && columnIndex > 0) {
|
3479
|
-
columnIndex--;
|
3480
|
-
showRow = showRow || data.rowArray[columnIndex].indexOf(data.iFilter) === 0;
|
3481
|
-
}
|
3482
|
-
} else {
|
3483
|
-
showRow = (data.iExact + data.childRowText).indexOf(data.iFilter) >= 0;
|
3484
|
-
}
|
3485
|
-
}
|
3486
|
-
data.anyMatch = false;
|
3749
|
+
if ( isChild || ( searchFiltered && regex.filtered.test( txt ) ) ) {
|
3750
|
+
continue;
|
3487
3751
|
}
|
3488
3752
|
|
3489
|
-
|
3490
|
-
|
3491
|
-
|
3492
|
-
|
3493
|
-
|
3494
|
-
|
3495
|
-
|
3496
|
-
|
3497
|
-
|
3498
|
-
|
3499
|
-
|
3500
|
-
|
3501
|
-
|
3502
|
-
|
3503
|
-
|
3504
|
-
|
3505
|
-
|
3506
|
-
|
3507
|
-
|
3508
|
-
|
3509
|
-
|
3510
|
-
// in case select filter option has a different value vs text "a - z|A through Z"
|
3511
|
-
ffxn = wo.filter_columnFilters ?
|
3512
|
-
c.$filters.add(c.$externalFilters).filter('[data-column="'+ columnIndex + '"]').find('select option:selected').attr('data-function-name') || '' : '';
|
3513
|
-
// replace accents - see #357
|
3514
|
-
if (c.sortLocaleCompare) {
|
3515
|
-
data.filter = ts.replaceAccents(data.filter);
|
3516
|
-
}
|
3753
|
+
data.$row = $rows.eq( rowIndex );
|
3754
|
+
data.cacheArray = norm_rows[ rowIndex ];
|
3755
|
+
rowData = data.cacheArray[ c.columns ];
|
3756
|
+
data.rawArray = rowData.raw;
|
3757
|
+
data.childRowText = '';
|
3758
|
+
|
3759
|
+
if ( !wo.filter_childByColumn ) {
|
3760
|
+
txt = '';
|
3761
|
+
// child row cached text
|
3762
|
+
childRow = rowData.child;
|
3763
|
+
// so, if 'table.config.widgetOptions.filter_childRows' is true and there is
|
3764
|
+
// a match anywhere in the child row, then it will make the row visible
|
3765
|
+
// checked here so the option can be changed dynamically
|
3766
|
+
for ( indx = 0; indx < childRow.length; indx++ ) {
|
3767
|
+
txt += ' ' + childRow[indx].join( '' ) || '';
|
3768
|
+
}
|
3769
|
+
data.childRowText = wo.filter_childRows ?
|
3770
|
+
( wo.filter_ignoreCase ? txt.toLowerCase() : txt ) :
|
3771
|
+
'';
|
3772
|
+
}
|
3517
3773
|
|
3518
|
-
|
3519
|
-
|
3520
|
-
|
3521
|
-
|
3522
|
-
|
3523
|
-
|
3524
|
-
|
3525
|
-
|
3526
|
-
|
3527
|
-
|
3528
|
-
|
3529
|
-
|
3530
|
-
if ( fxn || ( hasSelect && val ) ) {
|
3531
|
-
if (fxn === true || hasSelect) {
|
3532
|
-
// default selector uses exact match unless "filter-match" class is found
|
3533
|
-
filterMatched = ($cell.hasClass('filter-match')) ? data.iExact.search(data.iFilter) >= 0 : data.filter === data.exact;
|
3534
|
-
} else if (typeof fxn === 'function') {
|
3535
|
-
// filter callback( exact cell content, parser normalized content, filter input value, column index, jQuery row object )
|
3536
|
-
filterMatched = fxn(data.exact, data.cache, data.filter, columnIndex, $rows.eq(rowIndex), c);
|
3537
|
-
} else if (typeof fxn[ffxn || data.filter] === 'function') {
|
3538
|
-
// selector option function
|
3539
|
-
filterMatched = fxn[ffxn || data.filter](data.exact, data.cache, data.filter, columnIndex, $rows.eq(rowIndex), c);
|
3540
|
-
}
|
3774
|
+
showRow = ts.filter.processRow( c, data, vars );
|
3775
|
+
childRow = rowData.$row.filter( ':gt( 0 )' );
|
3776
|
+
|
3777
|
+
if ( wo.filter_childRows && childRow.length ) {
|
3778
|
+
if ( wo.filter_childByColumn ) {
|
3779
|
+
// cycle through each child row
|
3780
|
+
for ( indx = 0; indx < childRow.length; indx++ ) {
|
3781
|
+
data.$row = childRow.eq( indx );
|
3782
|
+
data.cacheArray = rowData.child[ indx ];
|
3783
|
+
data.rawArray = data.cacheArray;
|
3784
|
+
// use OR comparison on child rows
|
3785
|
+
showRow = showRow || ts.filter.processRow( c, data, vars );
|
3541
3786
|
}
|
3542
|
-
if (filterMatched === null) {
|
3543
|
-
// cycle through the different filters
|
3544
|
-
// filters return a boolean or null if nothing matches
|
3545
|
-
$.each(ts.filter.types, function(type, typeFunction) {
|
3546
|
-
if ($.inArray(type, excludeMatch) < 0) {
|
3547
|
-
matches = typeFunction( c, data );
|
3548
|
-
if (matches !== null) {
|
3549
|
-
filterMatched = matches;
|
3550
|
-
return false;
|
3551
|
-
}
|
3552
|
-
}
|
3553
|
-
});
|
3554
|
-
if (filterMatched !== null) {
|
3555
|
-
result = filterMatched;
|
3556
|
-
// Look for match, and add child row data for matching
|
3557
|
-
} else {
|
3558
|
-
data.exact = (data.iExact + data.childRowText).indexOf( ts.filter.parseFilter(c, data.iFilter, columnIndex, data.parsed[columnIndex]) );
|
3559
|
-
result = ( (!wo.filter_startsWith && data.exact >= 0) || (wo.filter_startsWith && data.exact === 0) );
|
3560
|
-
}
|
3561
|
-
} else {
|
3562
|
-
result = filterMatched;
|
3563
|
-
}
|
3564
|
-
showRow = (result) ? showRow : false;
|
3565
3787
|
}
|
3788
|
+
childRow.toggleClass( wo.filter_filteredRow, !showRow );
|
3566
3789
|
}
|
3567
|
-
|
3568
|
-
|
3790
|
+
|
3791
|
+
rowData.$row
|
3792
|
+
.toggleClass( wo.filter_filteredRow, !showRow )[0]
|
3569
3793
|
.display = showRow ? '' : 'none';
|
3570
|
-
if (childRow.length) {
|
3571
|
-
childRow.toggleClass(wo.filter_filteredRow, !showRow);
|
3572
|
-
}
|
3573
3794
|
}
|
3574
3795
|
}
|
3575
|
-
c.filteredRows += $rows.not('.' + wo.filter_filteredRow).length;
|
3796
|
+
c.filteredRows += $rows.not( '.' + wo.filter_filteredRow ).length;
|
3576
3797
|
c.totalRows += $rows.length;
|
3577
|
-
ts.processTbody(table, $tbody, false);
|
3798
|
+
ts.processTbody( table, $tbody, false );
|
3578
3799
|
}
|
3579
3800
|
c.lastCombinedFilter = combinedFilters; // save last search
|
3580
|
-
|
3581
|
-
c
|
3582
|
-
|
3583
|
-
|
3801
|
+
// don't save 'filters' directly since it may have altered ( AnyMatch column searches )
|
3802
|
+
c.lastSearch = storedFilters;
|
3803
|
+
c.$table.data( 'lastSearch', storedFilters );
|
3804
|
+
if ( wo.filter_saveFilters && ts.storage ) {
|
3805
|
+
ts.storage( table, 'tablesorter-filters', storedFilters );
|
3584
3806
|
}
|
3585
|
-
if (c.debug) {
|
3586
|
-
ts.benchmark(
|
3807
|
+
if ( c.debug ) {
|
3808
|
+
ts.benchmark( 'Completed filter widget search', time );
|
3809
|
+
}
|
3810
|
+
if ( wo.filter_initialized ) {
|
3811
|
+
c.$table.trigger( 'filterEnd', c );
|
3587
3812
|
}
|
3588
|
-
|
3589
|
-
|
3590
|
-
|
3591
|
-
}, 0);
|
3813
|
+
setTimeout( function() {
|
3814
|
+
c.$table.trigger( 'applyWidgets' ); // make sure zebra widget is applied
|
3815
|
+
}, 0 );
|
3592
3816
|
},
|
3593
|
-
getOptionSource: function(table, column, onlyAvail) {
|
3594
|
-
table = $(table)[0];
|
3817
|
+
getOptionSource: function( table, column, onlyAvail ) {
|
3818
|
+
table = $( table )[0];
|
3595
3819
|
var cts, indx, len,
|
3596
3820
|
c = table.config,
|
3597
3821
|
wo = c.widgetOptions,
|
3598
3822
|
parsed = [],
|
3599
3823
|
arry = false,
|
3600
3824
|
source = wo.filter_selectSource,
|
3601
|
-
last = c.$table.data('lastSearch') || [],
|
3602
|
-
fxn = $.isFunction(source) ? true : ts.getColumnData( table, source, column );
|
3825
|
+
last = c.$table.data( 'lastSearch' ) || [],
|
3826
|
+
fxn = $.isFunction( source ) ? true : ts.getColumnData( table, source, column );
|
3603
3827
|
|
3604
|
-
if (onlyAvail && last[column] !== '') {
|
3828
|
+
if ( onlyAvail && last[column] !== '' ) {
|
3605
3829
|
onlyAvail = false;
|
3606
3830
|
}
|
3607
3831
|
|
3608
3832
|
// filter select source option
|
3609
|
-
if (fxn === true) {
|
3833
|
+
if ( fxn === true ) {
|
3610
3834
|
// OVERALL source
|
3611
|
-
arry = source(table, column, onlyAvail);
|
3612
|
-
} else if ( fxn instanceof $ || ($.type(fxn) === 'string' && fxn.indexOf('</option>') >= 0) ) {
|
3835
|
+
arry = source( table, column, onlyAvail );
|
3836
|
+
} else if ( fxn instanceof $ || ( $.type( fxn ) === 'string' && fxn.indexOf( '</option>' ) >= 0 ) ) {
|
3613
3837
|
// selectSource is a jQuery object or string of options
|
3614
3838
|
return fxn;
|
3615
|
-
} else if ($.isArray(fxn)) {
|
3839
|
+
} else if ( $.isArray( fxn ) ) {
|
3616
3840
|
arry = fxn;
|
3617
|
-
} else if ($.type(source) === 'object' && fxn) {
|
3841
|
+
} else if ( $.type( source ) === 'object' && fxn ) {
|
3618
3842
|
// custom select source function for a SPECIFIC COLUMN
|
3619
|
-
arry = fxn(table, column, onlyAvail);
|
3843
|
+
arry = fxn( table, column, onlyAvail );
|
3620
3844
|
}
|
3621
|
-
if (arry === false) {
|
3845
|
+
if ( arry === false ) {
|
3622
3846
|
// fall back to original method
|
3623
|
-
arry = ts.filter.getOptions(table, column, onlyAvail);
|
3847
|
+
arry = ts.filter.getOptions( table, column, onlyAvail );
|
3624
3848
|
}
|
3625
3849
|
|
3626
3850
|
// get unique elements and sort the list
|
3627
|
-
// if $.tablesorter.sortText exists (not in the original tablesorter),
|
3851
|
+
// if $.tablesorter.sortText exists ( not in the original tablesorter ),
|
3628
3852
|
// then natural sort the list otherwise use a basic sort
|
3629
|
-
arry = $.grep(arry, function(value, indx) {
|
3630
|
-
return $.inArray(value, arry) === indx;
|
3853
|
+
arry = $.grep( arry, function( value, indx ) {
|
3854
|
+
return $.inArray( value, arry ) === indx;
|
3631
3855
|
});
|
3632
3856
|
|
3633
|
-
if (c.$headerIndexed[column].hasClass('filter-select-nosort')) {
|
3857
|
+
if ( c.$headerIndexed[ column ].hasClass( 'filter-select-nosort' ) ) {
|
3634
3858
|
// unsorted select options
|
3635
3859
|
return arry;
|
3636
3860
|
} else {
|
3637
3861
|
len = arry.length;
|
3638
3862
|
// parse select option values
|
3639
|
-
for (indx = 0; indx < len; indx++) {
|
3863
|
+
for ( indx = 0; indx < len; indx++ ) {
|
3640
3864
|
// parse array data using set column parser; this DOES NOT pass the original
|
3641
3865
|
// table cell to the parser format function
|
3642
|
-
parsed.push({
|
3866
|
+
parsed.push({
|
3867
|
+
t : arry[ indx ],
|
3868
|
+
p : c.parsers && c.parsers[ column ].format( arry[ indx ], table, [], column )
|
3869
|
+
});
|
3643
3870
|
}
|
3644
3871
|
|
3645
3872
|
// sort parsed select options
|
3646
3873
|
cts = c.textSorter || '';
|
3647
|
-
parsed.sort(function(a, b){
|
3874
|
+
parsed.sort( function( a, b ) {
|
3648
3875
|
// sortNatural breaks if you don't pass it strings
|
3649
|
-
var x = a.p.toString(),
|
3650
|
-
|
3876
|
+
var x = a.p.toString(),
|
3877
|
+
y = b.p.toString();
|
3878
|
+
if ( $.isFunction( cts ) ) {
|
3651
3879
|
// custom OVERALL text sorter
|
3652
|
-
return cts(x, y, true, column, table);
|
3653
|
-
} else if (typeof(cts) === 'object' && cts.hasOwnProperty(column)) {
|
3880
|
+
return cts( x, y, true, column, table );
|
3881
|
+
} else if ( typeof( cts ) === 'object' && cts.hasOwnProperty( column ) ) {
|
3654
3882
|
// custom text sorter for a SPECIFIC COLUMN
|
3655
|
-
return cts[column](x, y, true, column, table);
|
3656
|
-
} else if (ts.sortNatural) {
|
3883
|
+
return cts[column]( x, y, true, column, table );
|
3884
|
+
} else if ( ts.sortNatural ) {
|
3657
3885
|
// fall back to natural sort
|
3658
|
-
return ts.sortNatural(x, y);
|
3886
|
+
return ts.sortNatural( x, y );
|
3659
3887
|
}
|
3660
3888
|
// using an older version! do a basic sort
|
3661
3889
|
return true;
|
@@ -3663,187 +3891,224 @@ ts.filter = {
|
|
3663
3891
|
// rebuild arry from sorted parsed data
|
3664
3892
|
arry = [];
|
3665
3893
|
len = parsed.length;
|
3666
|
-
for (indx = 0; indx < len; indx++) {
|
3894
|
+
for ( indx = 0; indx < len; indx++ ) {
|
3667
3895
|
arry.push( parsed[indx].t );
|
3668
3896
|
}
|
3669
3897
|
return arry;
|
3670
3898
|
}
|
3671
3899
|
},
|
3672
|
-
getOptions: function(table, column, onlyAvail) {
|
3673
|
-
table = $(table)[0];
|
3674
|
-
var rowIndex, tbodyIndex, len, row, cache,
|
3900
|
+
getOptions: function( table, column, onlyAvail ) {
|
3901
|
+
table = $( table )[0];
|
3902
|
+
var rowIndex, tbodyIndex, len, row, cache,
|
3675
3903
|
c = table.config,
|
3676
3904
|
wo = c.widgetOptions,
|
3677
3905
|
arry = [];
|
3678
|
-
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
|
3906
|
+
for ( tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
|
3679
3907
|
cache = c.cache[tbodyIndex];
|
3680
3908
|
len = c.cache[tbodyIndex].normalized.length;
|
3681
3909
|
// loop through the rows
|
3682
|
-
for (rowIndex = 0; rowIndex < len; rowIndex++) {
|
3683
|
-
// get cached row from cache.row (old) or row data object
|
3684
|
-
|
3910
|
+
for ( rowIndex = 0; rowIndex < len; rowIndex++ ) {
|
3911
|
+
// get cached row from cache.row ( old ) or row data object
|
3912
|
+
// ( new; last item in normalized array )
|
3913
|
+
row = cache.row ?
|
3914
|
+
cache.row[ rowIndex ] :
|
3915
|
+
cache.normalized[ rowIndex ][ c.columns ].$row[0];
|
3685
3916
|
// check if has class filtered
|
3686
|
-
if (onlyAvail && row.className.match(wo.filter_filteredRow)) {
|
3917
|
+
if ( onlyAvail && row.className.match( wo.filter_filteredRow ) ) {
|
3918
|
+
continue;
|
3919
|
+
}
|
3687
3920
|
// get non-normalized cell content
|
3688
|
-
if (wo.filter_useParsedData ||
|
3689
|
-
|
3921
|
+
if ( wo.filter_useParsedData ||
|
3922
|
+
c.parsers[column].parsed ||
|
3923
|
+
c.$headerIndexed[column].hasClass( 'filter-parsed' ) ) {
|
3924
|
+
arry.push( '' + cache.normalized[ rowIndex ][ column ] );
|
3690
3925
|
} else {
|
3691
|
-
|
3692
|
-
|
3693
|
-
arry.push( $.trim( cell.getAttribute( c.textAttribute ) || cell.textContent || $(cell).text() ) );
|
3694
|
-
}
|
3926
|
+
// get raw cached data instead of content directly from the cells
|
3927
|
+
arry.push( cache.normalized[ rowIndex ][ c.columns ].raw[ column ] );
|
3695
3928
|
}
|
3696
3929
|
}
|
3697
3930
|
}
|
3698
3931
|
return arry;
|
3699
3932
|
},
|
3700
|
-
buildSelect: function(table, column, arry, updating, onlyAvail) {
|
3701
|
-
table = $(table)[0];
|
3702
|
-
column = parseInt(column, 10);
|
3703
|
-
if (!table.config.cache || $.isEmptyObject(table.config.cache)) {
|
3933
|
+
buildSelect: function( table, column, arry, updating, onlyAvail ) {
|
3934
|
+
table = $( table )[0];
|
3935
|
+
column = parseInt( column, 10 );
|
3936
|
+
if ( !table.config.cache || $.isEmptyObject( table.config.cache ) ) {
|
3937
|
+
return;
|
3938
|
+
}
|
3704
3939
|
var indx, val, txt, t, $filters, $filter,
|
3705
3940
|
c = table.config,
|
3706
3941
|
wo = c.widgetOptions,
|
3707
|
-
node = c.$headerIndexed[column],
|
3708
|
-
// t.data('placeholder') won't work in jQuery older than 1.4.3
|
3709
|
-
options = '<option value="">' +
|
3942
|
+
node = c.$headerIndexed[ column ],
|
3943
|
+
// t.data( 'placeholder' ) won't work in jQuery older than 1.4.3
|
3944
|
+
options = '<option value="">' +
|
3945
|
+
( node.data( 'placeholder' ) ||
|
3946
|
+
node.attr( 'data-placeholder' ) ||
|
3947
|
+
wo.filter_placeholder.select || ''
|
3948
|
+
) + '</option>',
|
3710
3949
|
// Get curent filter value
|
3711
|
-
currentValue = c.$table
|
3712
|
-
|
3713
|
-
|
3714
|
-
|
3950
|
+
currentValue = c.$table
|
3951
|
+
.find( 'thead' )
|
3952
|
+
.find( 'select.' + tscss.filter + '[data-column="' + column + '"]' )
|
3953
|
+
.val();
|
3954
|
+
// nothing included in arry ( external source ), so get the options from
|
3955
|
+
// filter_selectSource or column data
|
3956
|
+
if ( typeof arry === 'undefined' || arry === '' ) {
|
3957
|
+
arry = ts.filter.getOptionSource( table, column, onlyAvail );
|
3715
3958
|
}
|
3716
3959
|
|
3717
|
-
if ($.isArray(arry)) {
|
3960
|
+
if ( $.isArray( arry ) ) {
|
3718
3961
|
// build option list
|
3719
|
-
for (indx = 0; indx < arry.length; indx++) {
|
3720
|
-
txt = arry[indx] = ('' + arry[indx]).replace(/\"/g,
|
3962
|
+
for ( indx = 0; indx < arry.length; indx++ ) {
|
3963
|
+
txt = arry[indx] = ( '' + arry[indx] ).replace( /\"/g, '"' );
|
3721
3964
|
val = txt;
|
3722
3965
|
// allow including a symbol in the selectSource array
|
3723
|
-
//
|
3724
|
-
// and
|
3725
|
-
if (txt.indexOf(wo.filter_selectSourceSeparator) >= 0) {
|
3726
|
-
t = txt.split(wo.filter_selectSourceSeparator);
|
3966
|
+
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
3967
|
+
// and 'A through Z' becomes the option text
|
3968
|
+
if ( txt.indexOf( wo.filter_selectSourceSeparator ) >= 0 ) {
|
3969
|
+
t = txt.split( wo.filter_selectSourceSeparator );
|
3727
3970
|
val = t[0];
|
3728
3971
|
txt = t[1];
|
3729
3972
|
}
|
3730
|
-
// replace quotes - fixes #242 & ignore empty strings
|
3731
|
-
|
3973
|
+
// replace quotes - fixes #242 & ignore empty strings
|
3974
|
+
// see http://stackoverflow.com/q/14990971/145346
|
3975
|
+
options += arry[indx] !== '' ?
|
3976
|
+
'<option ' +
|
3977
|
+
( val === txt ? '' : 'data-function-name="' + arry[indx] + '" ' ) +
|
3978
|
+
'value="' + val + '">' + txt +
|
3979
|
+
'</option>' : '';
|
3732
3980
|
}
|
3733
3981
|
// clear arry so it doesn't get appended twice
|
3734
3982
|
arry = [];
|
3735
3983
|
}
|
3736
3984
|
|
3737
|
-
// update all selects in the same column (clone thead in sticky headers &
|
3738
|
-
|
3739
|
-
|
3740
|
-
|
3985
|
+
// update all selects in the same column ( clone thead in sticky headers &
|
3986
|
+
// any external selects ) - fixes 473
|
3987
|
+
$filters = ( c.$filters ? c.$filters : c.$table.children( 'thead' ) )
|
3988
|
+
.find( '.' + tscss.filter );
|
3989
|
+
if ( wo.filter_$externalFilters ) {
|
3990
|
+
$filters = $filters && $filters.length ?
|
3991
|
+
$filters.add( wo.filter_$externalFilters ) :
|
3992
|
+
wo.filter_$externalFilters;
|
3741
3993
|
}
|
3742
|
-
$filter = $filters.filter('select[data-column="' + column + '"]');
|
3994
|
+
$filter = $filters.filter( 'select[data-column="' + column + '"]' );
|
3743
3995
|
|
3744
3996
|
// make sure there is a select there!
|
3745
|
-
if ($filter.length) {
|
3746
|
-
$filter[ updating ? 'html' : 'append' ](options);
|
3747
|
-
if (!$.isArray(arry)) {
|
3997
|
+
if ( $filter.length ) {
|
3998
|
+
$filter[ updating ? 'html' : 'append' ]( options );
|
3999
|
+
if ( !$.isArray( arry ) ) {
|
3748
4000
|
// append options if arry is provided externally as a string or jQuery object
|
3749
|
-
// options (default value) was already added
|
3750
|
-
$filter.append(arry).val(currentValue);
|
4001
|
+
// options ( default value ) was already added
|
4002
|
+
$filter.append( arry ).val( currentValue );
|
3751
4003
|
}
|
3752
|
-
$filter.val(currentValue);
|
4004
|
+
$filter.val( currentValue );
|
3753
4005
|
}
|
3754
4006
|
},
|
3755
|
-
buildDefault: function(table, updating) {
|
4007
|
+
buildDefault: function( table, updating ) {
|
3756
4008
|
var columnIndex, $header, noSelect,
|
3757
4009
|
c = table.config,
|
3758
4010
|
wo = c.widgetOptions,
|
3759
4011
|
columns = c.columns;
|
3760
4012
|
// build default select dropdown
|
3761
|
-
for (columnIndex = 0; columnIndex < columns; columnIndex++) {
|
4013
|
+
for ( columnIndex = 0; columnIndex < columns; columnIndex++ ) {
|
3762
4014
|
$header = c.$headerIndexed[columnIndex];
|
3763
|
-
noSelect = !($header.hasClass('filter-false') || $header.hasClass('parser-false'));
|
4015
|
+
noSelect = !( $header.hasClass( 'filter-false' ) || $header.hasClass( 'parser-false' ) );
|
3764
4016
|
// look for the filter-select class; build/update it if found
|
3765
|
-
if (($header.hasClass('filter-select') ||
|
3766
|
-
ts.
|
4017
|
+
if ( ( $header.hasClass( 'filter-select' ) ||
|
4018
|
+
ts.getColumnData( table, wo.filter_functions, columnIndex ) === true ) && noSelect ) {
|
4019
|
+
ts.filter.buildSelect( table, columnIndex, '', updating, $header.hasClass( wo.filter_onlyAvail ) );
|
3767
4020
|
}
|
3768
4021
|
}
|
3769
4022
|
}
|
3770
4023
|
};
|
3771
4024
|
|
3772
|
-
ts.getFilters = function(table, getRaw, setFilters, skipFirst) {
|
4025
|
+
ts.getFilters = function( table, getRaw, setFilters, skipFirst ) {
|
3773
4026
|
var i, $filters, $column, cols,
|
3774
4027
|
filters = false,
|
3775
|
-
c = table ? $(table)[0].config : '',
|
4028
|
+
c = table ? $( table )[0].config : '',
|
3776
4029
|
wo = c ? c.widgetOptions : '';
|
3777
|
-
if (getRaw !== true && wo && !wo.filter_columnFilters)
|
3778
|
-
|
4030
|
+
if ( ( getRaw !== true && wo && !wo.filter_columnFilters ) ||
|
4031
|
+
// setFilters called, but last search is exactly the same as the current
|
4032
|
+
// fixes issue #733 & #903 where calling update causes the input values to reset
|
4033
|
+
( $.isArray(setFilters) && setFilters.join('') === c.lastCombinedFilter ) ) {
|
4034
|
+
return $( table ).data( 'lastSearch' );
|
3779
4035
|
}
|
3780
|
-
if (c) {
|
3781
|
-
if (c.$filters) {
|
3782
|
-
$filters = c.$filters.find('.' + tscss.filter);
|
4036
|
+
if ( c ) {
|
4037
|
+
if ( c.$filters ) {
|
4038
|
+
$filters = c.$filters.find( '.' + tscss.filter );
|
3783
4039
|
}
|
3784
|
-
if (wo.filter_$externalFilters) {
|
3785
|
-
$filters = $filters && $filters.length ?
|
4040
|
+
if ( wo.filter_$externalFilters ) {
|
4041
|
+
$filters = $filters && $filters.length ?
|
4042
|
+
$filters.add( wo.filter_$externalFilters ) :
|
4043
|
+
wo.filter_$externalFilters;
|
3786
4044
|
}
|
3787
|
-
if ($filters && $filters.length) {
|
4045
|
+
if ( $filters && $filters.length ) {
|
3788
4046
|
filters = setFilters || [];
|
3789
|
-
for (i = 0; i < c.columns + 1; i++) {
|
4047
|
+
for ( i = 0; i < c.columns + 1; i++ ) {
|
3790
4048
|
cols = ( i === c.columns ?
|
3791
|
-
//
|
4049
|
+
// 'all' columns can now include a range or set of columms ( data-column='0-2,4,6-7' )
|
3792
4050
|
wo.filter_anyColumnSelector + ',' + wo.filter_multipleColumnSelector :
|
3793
4051
|
'[data-column="' + i + '"]' );
|
3794
|
-
$column = $filters.filter(cols);
|
3795
|
-
if ($column.length) {
|
4052
|
+
$column = $filters.filter( cols );
|
4053
|
+
if ( $column.length ) {
|
3796
4054
|
// move the latest search to the first slot in the array
|
3797
4055
|
$column = ts.filter.getLatestSearch( $column );
|
3798
|
-
if ($.isArray(setFilters)) {
|
3799
|
-
// skip first (latest input) to maintain cursor position while typing
|
3800
|
-
if (skipFirst) {
|
3801
|
-
|
3802
|
-
|
3803
|
-
|
4056
|
+
if ( $.isArray( setFilters ) ) {
|
4057
|
+
// skip first ( latest input ) to maintain cursor position while typing
|
4058
|
+
if ( skipFirst ) {
|
4059
|
+
$column.slice( 1 );
|
4060
|
+
}
|
4061
|
+
if ( i === c.columns ) {
|
4062
|
+
// prevent data-column='all' from filling data-column='0,1' ( etc )
|
4063
|
+
cols = $column.filter( wo.filter_anyColumnSelector );
|
3804
4064
|
$column = cols.length ? cols : $column;
|
3805
4065
|
}
|
3806
4066
|
$column
|
3807
|
-
.val( setFilters[i] )
|
3808
|
-
.trigger('change.tsfilter');
|
4067
|
+
.val( setFilters[ i ] )
|
4068
|
+
.trigger( 'change.tsfilter' );
|
3809
4069
|
} else {
|
3810
4070
|
filters[i] = $column.val() || '';
|
3811
4071
|
// don't change the first... it will move the cursor
|
3812
|
-
if (i === c.columns) {
|
3813
|
-
// don't update range columns from
|
3814
|
-
$column
|
4072
|
+
if ( i === c.columns ) {
|
4073
|
+
// don't update range columns from 'all' setting
|
4074
|
+
$column
|
4075
|
+
.slice( 1 )
|
4076
|
+
.filter( '[data-column*="' + $column.attr( 'data-column' ) + '"]' )
|
4077
|
+
.val( filters[ i ] );
|
3815
4078
|
} else {
|
3816
|
-
$column
|
4079
|
+
$column
|
4080
|
+
.slice( 1 )
|
4081
|
+
.val( filters[ i ] );
|
3817
4082
|
}
|
3818
4083
|
}
|
3819
4084
|
// save any match input dynamically
|
3820
|
-
if (i === c.columns && $column.length) {
|
4085
|
+
if ( i === c.columns && $column.length ) {
|
3821
4086
|
wo.filter_$anyMatch = $column;
|
3822
4087
|
}
|
3823
4088
|
}
|
3824
4089
|
}
|
3825
4090
|
}
|
3826
4091
|
}
|
3827
|
-
if (filters.length === 0) {
|
4092
|
+
if ( filters.length === 0 ) {
|
3828
4093
|
filters = false;
|
3829
4094
|
}
|
3830
4095
|
return filters;
|
3831
4096
|
};
|
3832
4097
|
|
3833
|
-
ts.setFilters = function(table, filter, apply, skipFirst) {
|
3834
|
-
var c = table ? $(table)[0].config : '',
|
3835
|
-
valid = ts.getFilters(table, true, filter, skipFirst);
|
3836
|
-
if (c && apply) {
|
4098
|
+
ts.setFilters = function( table, filter, apply, skipFirst ) {
|
4099
|
+
var c = table ? $( table )[0].config : '',
|
4100
|
+
valid = ts.getFilters( table, true, filter, skipFirst );
|
4101
|
+
if ( c && apply ) {
|
3837
4102
|
// ensure new set filters are applied, even if the search is the same
|
3838
4103
|
c.lastCombinedFilter = null;
|
3839
4104
|
c.lastSearch = [];
|
3840
|
-
ts.filter.searching(c.table, filter, skipFirst);
|
3841
|
-
c.$table.trigger('filterFomatterUpdate');
|
4105
|
+
ts.filter.searching( c.table, filter, skipFirst );
|
4106
|
+
c.$table.trigger( 'filterFomatterUpdate' );
|
3842
4107
|
}
|
3843
4108
|
return !!valid;
|
3844
4109
|
};
|
3845
4110
|
|
3846
|
-
})(jQuery);
|
4111
|
+
})( jQuery );
|
3847
4112
|
|
3848
4113
|
/*! Widget: stickyHeaders - updated 3/26/2015 (v2.21.3) *//*
|
3849
4114
|
* Requires tablesorter v2.8+ and jQuery 1.4.3+
|
@@ -3851,7 +4116,7 @@ ts.setFilters = function(table, filter, apply, skipFirst) {
|
|
3851
4116
|
*/
|
3852
4117
|
;(function ($, window) {
|
3853
4118
|
'use strict';
|
3854
|
-
var ts = $.tablesorter
|
4119
|
+
var ts = $.tablesorter || {};
|
3855
4120
|
|
3856
4121
|
$.extend(ts.css, {
|
3857
4122
|
sticky : 'tablesorter-stickyHeader', // stickyHeader
|
@@ -4117,10 +4382,10 @@ ts.addWidget({
|
|
4117
4382
|
|
4118
4383
|
})(jQuery, window);
|
4119
4384
|
|
4120
|
-
/*! Widget: resizable - updated
|
4385
|
+
/*! Widget: resizable - updated 5/17/2015 (v2.22.0) */
|
4121
4386
|
;(function ($, window) {
|
4122
4387
|
'use strict';
|
4123
|
-
var ts = $.tablesorter
|
4388
|
+
var ts = $.tablesorter || {};
|
4124
4389
|
|
4125
4390
|
$.extend(ts.css, {
|
4126
4391
|
resizableContainer : 'tablesorter-resizable-container',
|
@@ -4409,7 +4674,7 @@ ts.addWidget({
|
|
4409
4674
|
init: function(table, thisWidget, c, wo) {
|
4410
4675
|
ts.resizable.init( c, wo );
|
4411
4676
|
},
|
4412
|
-
remove: function( table, c, wo ) {
|
4677
|
+
remove: function( table, c, wo, refreshing ) {
|
4413
4678
|
if (wo.$resizable_container) {
|
4414
4679
|
var namespace = c.namespace + 'tsresize';
|
4415
4680
|
c.$table.add( $( c.namespace + '_extra_table' ) )
|
@@ -4418,13 +4683,13 @@ ts.addWidget({
|
|
4418
4683
|
|
4419
4684
|
wo.$resizable_container.remove();
|
4420
4685
|
ts.resizable.toggleTextSelection( c, false );
|
4421
|
-
ts.resizableReset( table );
|
4686
|
+
ts.resizableReset( table, refreshing );
|
4422
4687
|
$( document ).unbind( 'mousemove' + namespace + ' mouseup' + namespace );
|
4423
4688
|
}
|
4424
4689
|
}
|
4425
4690
|
});
|
4426
4691
|
|
4427
|
-
ts.resizableReset = function( table,
|
4692
|
+
ts.resizableReset = function( table, refreshing ) {
|
4428
4693
|
$( table ).each(function(){
|
4429
4694
|
var index, $t,
|
4430
4695
|
c = this.config,
|
@@ -4441,7 +4706,7 @@ ts.resizableReset = function( table, nosave ) {
|
|
4441
4706
|
}
|
4442
4707
|
// reset stickyHeader widths
|
4443
4708
|
$( window ).trigger( 'resize' );
|
4444
|
-
if ( ts.storage && !
|
4709
|
+
if ( ts.storage && !refreshing ) {
|
4445
4710
|
ts.storage( this, ts.css.resizableStorage, {} );
|
4446
4711
|
}
|
4447
4712
|
}
|
@@ -4453,7 +4718,7 @@ ts.resizableReset = function( table, nosave ) {
|
|
4453
4718
|
/*! Widget: saveSort */
|
4454
4719
|
;(function ($) {
|
4455
4720
|
'use strict';
|
4456
|
-
var ts = $.tablesorter
|
4721
|
+
var ts = $.tablesorter || {};
|
4457
4722
|
|
4458
4723
|
// this widget saves the last sort only if the
|
4459
4724
|
// saveSort widget option is true AND the
|