jquery-tablesorter 1.19.1 → 1.19.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +9 -5
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +201 -168
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +59 -47
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +142 -121
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-file-type.js +24 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +141 -120
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-headerTitles.js +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +6 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +8 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +45 -23
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-toggle.js +81 -0
- metadata +3 -2
@@ -4,7 +4,7 @@
|
|
4
4
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀██
|
5
5
|
█████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
|
6
6
|
*/
|
7
|
-
/*! tablesorter (FORK) - updated 11-
|
7
|
+
/*! tablesorter (FORK) - updated 11-10-2015 (v2.24.4)*/
|
8
8
|
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
|
9
9
|
(function(factory) {
|
10
10
|
if (typeof define === 'function' && define.amd) {
|
@@ -372,13 +372,13 @@
|
|
372
372
|
|
373
373
|
})(jQuery);
|
374
374
|
|
375
|
-
/*! Widget: filter - updated 11/
|
375
|
+
/*! Widget: filter - updated 11/10/2015 (v2.24.4) *//*
|
376
376
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
377
377
|
* by Rob Garrison
|
378
378
|
*/
|
379
379
|
;( function ( $ ) {
|
380
380
|
'use strict';
|
381
|
-
var tsf,
|
381
|
+
var tsf, tsfRegex,
|
382
382
|
ts = $.tablesorter || {},
|
383
383
|
tscss = ts.css;
|
384
384
|
|
@@ -484,20 +484,21 @@
|
|
484
484
|
// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
|
485
485
|
types: {
|
486
486
|
or : function( c, data, vars ) {
|
487
|
-
|
487
|
+
// look for "|", but not if it is inside of a regular expression
|
488
|
+
if ( ( tsfRegex.orTest.test( data.iFilter ) || tsfRegex.orSplit.test( data.filter ) ) &&
|
489
|
+
// this test for regex has potential to slow down the overall search
|
490
|
+
!tsfRegex.regex.test( data.filter ) ) {
|
488
491
|
var indx, filterMatched, query, regex,
|
489
492
|
// duplicate data but split filter
|
490
493
|
data2 = $.extend( {}, data ),
|
491
|
-
|
492
|
-
|
493
|
-
filter = data.filter.split( tsf.regex.orSplit ),
|
494
|
-
iFilter = data.iFilter.split( tsf.regex.orSplit ),
|
494
|
+
filter = data.filter.split( tsfRegex.orSplit ),
|
495
|
+
iFilter = data.iFilter.split( tsfRegex.orSplit ),
|
495
496
|
len = filter.length;
|
496
497
|
for ( indx = 0; indx < len; indx++ ) {
|
497
498
|
data2.nestedFilters = true;
|
498
|
-
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ],
|
499
|
-
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ],
|
500
|
-
query = '(' + ( tsf.parseFilter( c, data2.filter,
|
499
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], data ) || '' );
|
500
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], data ) || '' );
|
501
|
+
query = '(' + ( tsf.parseFilter( c, data2.filter, data ) || '' ) + ')';
|
501
502
|
try {
|
502
503
|
// use try/catch, because query may not be a valid regex if "|" is contained within a partial regex search,
|
503
504
|
// e.g "/(Alex|Aar" -> Uncaught SyntaxError: Invalid regular expression: /(/(Alex)/: Unterminated group
|
@@ -519,22 +520,20 @@
|
|
519
520
|
},
|
520
521
|
// Look for an AND or && operator ( logical and )
|
521
522
|
and : function( c, data, vars ) {
|
522
|
-
if (
|
523
|
+
if ( tsfRegex.andTest.test( data.filter ) ) {
|
523
524
|
var indx, filterMatched, result, query, regex,
|
524
525
|
// duplicate data but split filter
|
525
526
|
data2 = $.extend( {}, data ),
|
526
|
-
|
527
|
-
|
528
|
-
filter = data.filter.split( tsf.regex.andSplit ),
|
529
|
-
iFilter = data.iFilter.split( tsf.regex.andSplit ),
|
527
|
+
filter = data.filter.split( tsfRegex.andSplit ),
|
528
|
+
iFilter = data.iFilter.split( tsfRegex.andSplit ),
|
530
529
|
len = filter.length;
|
531
530
|
for ( indx = 0; indx < len; indx++ ) {
|
532
531
|
data2.nestedFilters = true;
|
533
|
-
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ],
|
534
|
-
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ],
|
535
|
-
query = ( '(' + ( tsf.parseFilter( c, data2.filter,
|
532
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], data ) || '' );
|
533
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], data ) || '' );
|
534
|
+
query = ( '(' + ( tsf.parseFilter( c, data2.filter, data ) || '' ) + ')' )
|
536
535
|
// replace wild cards since /(a*)/i will match anything
|
537
|
-
.replace(
|
536
|
+
.replace( tsfRegex.wild01, '\\S{1}' ).replace( tsfRegex.wild0More, '\\S*' );
|
538
537
|
try {
|
539
538
|
// use try/catch just in case RegExp is invalid
|
540
539
|
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
@@ -556,10 +555,10 @@
|
|
556
555
|
},
|
557
556
|
// Look for regex
|
558
557
|
regex: function( c, data ) {
|
559
|
-
if (
|
558
|
+
if ( tsfRegex.regex.test( data.filter ) ) {
|
560
559
|
var matches,
|
561
560
|
// cache regex per column for optimal speed
|
562
|
-
regex = data.filter_regexCache[ data.index ] ||
|
561
|
+
regex = data.filter_regexCache[ data.index ] || tsfRegex.regex.exec( data.filter ),
|
563
562
|
isRegex = regex instanceof RegExp;
|
564
563
|
try {
|
565
564
|
if ( !isRegex ) {
|
@@ -578,18 +577,17 @@
|
|
578
577
|
// Look for operators >, >=, < or <=
|
579
578
|
operators: function( c, data ) {
|
580
579
|
// ignore empty strings... because '' < 10 is true
|
581
|
-
if (
|
580
|
+
if ( tsfRegex.operTest.test( data.iFilter ) && data.iExact !== '' ) {
|
582
581
|
var cachedValue, result, txt,
|
583
582
|
table = c.table,
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
parser = c.parsers[index],
|
583
|
+
parsed = data.parsed[ data.index ],
|
584
|
+
query = ts.formatFloat( data.iFilter.replace( tsfRegex.operators, '' ), table ),
|
585
|
+
parser = c.parsers[ data.index ],
|
588
586
|
savedSearch = query;
|
589
587
|
// parse filter value in case we're comparing numbers ( dates )
|
590
588
|
if ( parsed || parser.type === 'numeric' ) {
|
591
|
-
txt = $.trim( '' + data.iFilter.replace(
|
592
|
-
result = tsf.parseFilter( c, txt,
|
589
|
+
txt = $.trim( '' + data.iFilter.replace( tsfRegex.operators, '' ) );
|
590
|
+
result = tsf.parseFilter( c, txt, data, true );
|
593
591
|
query = ( typeof result === 'number' && result !== '' && !isNaN( result ) ) ? result : query;
|
594
592
|
}
|
595
593
|
// iExact may be numeric - see issue #149;
|
@@ -601,10 +599,10 @@
|
|
601
599
|
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
|
602
600
|
cachedValue = ts.formatFloat( txt, table );
|
603
601
|
}
|
604
|
-
if (
|
605
|
-
result =
|
606
|
-
} else if (
|
607
|
-
result =
|
602
|
+
if ( tsfRegex.gtTest.test( data.iFilter ) ) {
|
603
|
+
result = tsfRegex.gteTest.test( data.iFilter ) ? cachedValue >= query : cachedValue > query;
|
604
|
+
} else if ( tsfRegex.ltTest.test( data.iFilter ) ) {
|
605
|
+
result = tsfRegex.lteTest.test( data.iFilter ) ? cachedValue <= query : cachedValue < query;
|
608
606
|
}
|
609
607
|
// keep showing all rows if nothing follows the operator
|
610
608
|
if ( !result && savedSearch === '' ) {
|
@@ -616,13 +614,13 @@
|
|
616
614
|
},
|
617
615
|
// Look for a not match
|
618
616
|
notMatch: function( c, data ) {
|
619
|
-
if (
|
617
|
+
if ( tsfRegex.notTest.test( data.iFilter ) ) {
|
620
618
|
var indx,
|
621
619
|
txt = data.iFilter.replace( '!', '' ),
|
622
|
-
filter = tsf.parseFilter( c, txt, data
|
623
|
-
if (
|
620
|
+
filter = tsf.parseFilter( c, txt, data ) || '';
|
621
|
+
if ( tsfRegex.exact.test( filter ) ) {
|
624
622
|
// look for exact not matches - see #628
|
625
|
-
filter = filter.replace(
|
623
|
+
filter = filter.replace( tsfRegex.exact, '' );
|
626
624
|
return filter === '' ? true : $.trim( filter ) !== data.iExact;
|
627
625
|
} else {
|
628
626
|
indx = data.iExact.search( $.trim( filter ) );
|
@@ -634,29 +632,29 @@
|
|
634
632
|
// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
|
635
633
|
exact: function( c, data ) {
|
636
634
|
/*jshint eqeqeq:false */
|
637
|
-
if (
|
638
|
-
var txt = data.iFilter.replace(
|
639
|
-
filter = tsf.parseFilter( c, txt, data
|
635
|
+
if ( tsfRegex.exact.test( data.iFilter ) ) {
|
636
|
+
var txt = data.iFilter.replace( tsfRegex.exact, '' ),
|
637
|
+
filter = tsf.parseFilter( c, txt, data ) || '';
|
640
638
|
return data.anyMatch ? $.inArray( filter, data.rowArray ) >= 0 : filter == data.iExact;
|
641
639
|
}
|
642
640
|
return null;
|
643
641
|
},
|
644
642
|
// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
|
645
643
|
range : function( c, data ) {
|
646
|
-
if (
|
644
|
+
if ( tsfRegex.toTest.test( data.iFilter ) ) {
|
647
645
|
var result, tmp, range1, range2,
|
648
646
|
table = c.table,
|
649
647
|
index = data.index,
|
650
648
|
parsed = data.parsed[index],
|
651
649
|
// make sure the dash is for a range and not indicating a negative number
|
652
|
-
query = data.iFilter.split(
|
650
|
+
query = data.iFilter.split( tsfRegex.toSplit );
|
653
651
|
|
654
652
|
tmp = query[0].replace( ts.regex.nondigit, '' ) || '';
|
655
|
-
range1 = ts.formatFloat( tsf.parseFilter( c, tmp,
|
653
|
+
range1 = ts.formatFloat( tsf.parseFilter( c, tmp, data ), table );
|
656
654
|
tmp = query[1].replace( ts.regex.nondigit, '' ) || '';
|
657
|
-
range2 = ts.formatFloat( tsf.parseFilter( c, tmp,
|
655
|
+
range2 = ts.formatFloat( tsf.parseFilter( c, tmp, data ), table );
|
658
656
|
// parse filter value in case we're comparing numbers ( dates )
|
659
|
-
if ( parsed || c.parsers[index].type === 'numeric' ) {
|
657
|
+
if ( parsed || c.parsers[ index ].type === 'numeric' ) {
|
660
658
|
result = c.parsers[ index ].format( '' + query[0], table, c.$headers.eq( index ), index );
|
661
659
|
range1 = ( result !== '' && !isNaN( result ) ) ? result : range1;
|
662
660
|
result = c.parsers[ index ].format( '' + query[1], table, c.$headers.eq( index ), index );
|
@@ -677,18 +675,16 @@
|
|
677
675
|
},
|
678
676
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
679
677
|
wild : function( c, data ) {
|
680
|
-
if (
|
681
|
-
var
|
682
|
-
parsed = data.parsed[ index ],
|
683
|
-
query = '' + ( tsf.parseFilter( c, data.iFilter, index, parsed ) || '' );
|
678
|
+
if ( tsfRegex.wildOrTest.test( data.iFilter ) ) {
|
679
|
+
var query = '' + ( tsf.parseFilter( c, data.iFilter, data ) || '' );
|
684
680
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
685
|
-
if ( !
|
681
|
+
if ( !tsfRegex.wildTest.test( query ) && data.nestedFilters ) {
|
686
682
|
query = data.isMatch ? query : '^(' + query + ')$';
|
687
683
|
}
|
688
684
|
// parsing the filter may not work properly when using wildcards =/
|
689
685
|
try {
|
690
686
|
return new RegExp(
|
691
|
-
query.replace(
|
687
|
+
query.replace( tsfRegex.wild01, '\\S{1}' ).replace( tsfRegex.wild0More, '\\S*' ),
|
692
688
|
c.widgetOptions.filter_ignoreCase ? 'i' : ''
|
693
689
|
)
|
694
690
|
.test( data.exact );
|
@@ -700,21 +696,18 @@
|
|
700
696
|
},
|
701
697
|
// fuzzy text search; modified from https://github.com/mattyork/fuzzy ( MIT license )
|
702
698
|
fuzzy: function( c, data ) {
|
703
|
-
if (
|
699
|
+
if ( tsfRegex.fuzzyTest.test( data.iFilter ) ) {
|
704
700
|
var indx,
|
705
701
|
patternIndx = 0,
|
706
702
|
len = data.iExact.length,
|
707
703
|
txt = data.iFilter.slice( 1 ),
|
708
|
-
pattern = tsf.parseFilter( c, txt, data
|
704
|
+
pattern = tsf.parseFilter( c, txt, data ) || '';
|
709
705
|
for ( indx = 0; indx < len; indx++ ) {
|
710
706
|
if ( data.iExact[ indx ] === pattern[ patternIndx ] ) {
|
711
707
|
patternIndx += 1;
|
712
708
|
}
|
713
709
|
}
|
714
|
-
|
715
|
-
return true;
|
716
|
-
}
|
717
|
-
return false;
|
710
|
+
return patternIndx === pattern.length;
|
718
711
|
}
|
719
712
|
return null;
|
720
713
|
}
|
@@ -727,8 +720,7 @@
|
|
727
720
|
and : 'and'
|
728
721
|
}, ts.language );
|
729
722
|
|
730
|
-
var options, string, txt, $header, column, filters, val, fxn, noSelect
|
731
|
-
regex = tsf.regex;
|
723
|
+
var options, string, txt, $header, column, filters, val, fxn, noSelect;
|
732
724
|
c.$table.addClass( 'hasFilters' );
|
733
725
|
|
734
726
|
// define timers so using clearTimeout won't cause an undefined error
|
@@ -739,8 +731,8 @@
|
|
739
731
|
wo.filter_anyColumnSelector = '[data-column="all"],[data-column="any"]';
|
740
732
|
wo.filter_multipleColumnSelector = '[data-column*="-"],[data-column*=","]';
|
741
733
|
|
742
|
-
val = '\\{' +
|
743
|
-
$.extend(
|
734
|
+
val = '\\{' + tsfRegex.query + '\\}';
|
735
|
+
$.extend( tsfRegex, {
|
744
736
|
child : new RegExp( c.cssChildRow ),
|
745
737
|
filtered : new RegExp( wo.filter_filteredRow ),
|
746
738
|
alreadyFiltered : new RegExp( '(\\s+(' + ts.language.or + '|-|' + ts.language.to + ')\\s+)', 'i' ),
|
@@ -1018,8 +1010,10 @@
|
|
1018
1010
|
c.$table.data( 'lastSearch', filters );
|
1019
1011
|
return filters;
|
1020
1012
|
},
|
1021
|
-
parseFilter: function( c, filter,
|
1022
|
-
return parsed
|
1013
|
+
parseFilter: function( c, filter, data, parsed ) {
|
1014
|
+
return parsed || data.parsed[ data.index ] ?
|
1015
|
+
c.parsers[ data.index ].format( filter, c.table, [], data.index ) :
|
1016
|
+
filter;
|
1023
1017
|
},
|
1024
1018
|
buildRow: function( table, c, wo ) {
|
1025
1019
|
var $filter, col, column, $header, makeSelect, disabled, name, ffxn, tmp,
|
@@ -1212,8 +1206,12 @@
|
|
1212
1206
|
c.lastCombinedFilter = null;
|
1213
1207
|
c.lastSearch = [];
|
1214
1208
|
}
|
1215
|
-
// convert filters to strings
|
1216
|
-
filters =
|
1209
|
+
// convert filters to strings - see #1070
|
1210
|
+
filters = Array.prototype.map ?
|
1211
|
+
filters.map( String ) :
|
1212
|
+
// for IE8 & older browsers - maybe not the best method
|
1213
|
+
filters.join( '\u0000' ).split( '\u0000' );
|
1214
|
+
|
1217
1215
|
if ( wo.filter_initialized ) {
|
1218
1216
|
c.$table.trigger( 'filterStart', [ filters ] );
|
1219
1217
|
}
|
@@ -1267,8 +1265,8 @@
|
|
1267
1265
|
},
|
1268
1266
|
defaultFilter: function( filter, mask ) {
|
1269
1267
|
if ( filter === '' ) { return filter; }
|
1270
|
-
var regex =
|
1271
|
-
maskLen = mask.match(
|
1268
|
+
var regex = tsfRegex.iQuery,
|
1269
|
+
maskLen = mask.match( tsfRegex.igQuery ).length,
|
1272
1270
|
query = maskLen > 1 ? $.trim( filter ).split( /\s/ ) : [ $.trim( filter ) ],
|
1273
1271
|
len = query.length - 1,
|
1274
1272
|
indx = 0,
|
@@ -1365,9 +1363,8 @@
|
|
1365
1363
|
return filterMatched;
|
1366
1364
|
},
|
1367
1365
|
processRow: function( c, data, vars ) {
|
1368
|
-
var
|
1366
|
+
var result, filterMatched,
|
1369
1367
|
fxn, ffxn, txt,
|
1370
|
-
regex = tsf.regex,
|
1371
1368
|
wo = c.widgetOptions,
|
1372
1369
|
showRow = true,
|
1373
1370
|
|
@@ -1446,7 +1443,7 @@
|
|
1446
1443
|
result = data.rawArray[ columnIndex ] || '';
|
1447
1444
|
data.exact = c.sortLocaleCompare ? ts.replaceAccents( result ) : result; // issue #405
|
1448
1445
|
}
|
1449
|
-
data.iExact = !
|
1446
|
+
data.iExact = !tsfRegex.type.test( typeof data.exact ) && wo.filter_ignoreCase ?
|
1450
1447
|
data.exact.toLowerCase() : data.exact;
|
1451
1448
|
|
1452
1449
|
data.isMatch = c.$headerIndexed[ data.index ].hasClass( 'filter-match' );
|
@@ -1464,21 +1461,13 @@
|
|
1464
1461
|
data.filter = ts.replaceAccents( data.filter );
|
1465
1462
|
}
|
1466
1463
|
|
1467
|
-
val = true;
|
1468
|
-
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
1469
|
-
data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
1470
|
-
// val is used to indicate that a filter select is using a default filter;
|
1471
|
-
// so we override the exact & partial matches
|
1472
|
-
val = false;
|
1473
|
-
}
|
1474
1464
|
// data.iFilter = case insensitive ( if wo.filter_ignoreCase is true ),
|
1475
1465
|
// data.filter = case sensitive
|
1476
1466
|
data.iFilter = wo.filter_ignoreCase ? ( data.filter || '' ).toLowerCase() : data.filter;
|
1477
1467
|
fxn = vars.functions[ columnIndex ];
|
1478
|
-
hasSelect = c.$headerIndexed[ columnIndex ].hasClass( 'filter-select' );
|
1479
1468
|
filterMatched = null;
|
1480
|
-
if ( fxn
|
1481
|
-
if ( fxn === true
|
1469
|
+
if ( fxn ) {
|
1470
|
+
if ( fxn === true ) {
|
1482
1471
|
// default selector uses exact match unless 'filter-match' class is found
|
1483
1472
|
filterMatched = data.isMatch ?
|
1484
1473
|
// data.iExact may be a number
|
@@ -1504,7 +1493,7 @@
|
|
1504
1493
|
// Look for match, and add child row data for matching
|
1505
1494
|
} else {
|
1506
1495
|
txt = ( data.iExact + data.childRowText )
|
1507
|
-
.indexOf( tsf.parseFilter( c, data.iFilter,
|
1496
|
+
.indexOf( tsf.parseFilter( c, data.iFilter, data ) );
|
1508
1497
|
result = ( ( !wo.filter_startsWith && txt >= 0 ) || ( wo.filter_startsWith && txt === 0 ) );
|
1509
1498
|
}
|
1510
1499
|
} else {
|
@@ -1524,7 +1513,6 @@
|
|
1524
1513
|
isChild, childRow, lastSearch, showRow, showParent, time, val, indx,
|
1525
1514
|
notFiltered, searchFiltered, query, injected, res, id, txt,
|
1526
1515
|
storedFilters = $.extend( [], filters ),
|
1527
|
-
regex = tsf.regex,
|
1528
1516
|
c = table.config,
|
1529
1517
|
wo = c.widgetOptions,
|
1530
1518
|
// data object passed to filters; anyMatch is a flag for the filters
|
@@ -1606,7 +1594,7 @@
|
|
1606
1594
|
);
|
1607
1595
|
if ( wo.filter_columnAnyMatch ) {
|
1608
1596
|
// specific columns search
|
1609
|
-
query = data.anyMatchFilter.split(
|
1597
|
+
query = data.anyMatchFilter.split( tsfRegex.andSplit );
|
1610
1598
|
injected = false;
|
1611
1599
|
for ( indx = 0; indx < query.length; indx++ ) {
|
1612
1600
|
res = query[ indx ].split( ':' );
|
@@ -1641,12 +1629,12 @@
|
|
1641
1629
|
// there are no changes from beginning of filter
|
1642
1630
|
val.indexOf( lastSearch[indx] || '' ) === 0 &&
|
1643
1631
|
// if there is NOT a logical 'or', or range ( 'to' or '-' ) in the string
|
1644
|
-
!
|
1632
|
+
!tsfRegex.alreadyFiltered.test( val ) &&
|
1645
1633
|
// if we are not doing exact matches, using '|' ( logical or ) or not '!'
|
1646
|
-
!
|
1634
|
+
!tsfRegex.exactTest.test( val ) &&
|
1647
1635
|
// don't search only filtered if the value is negative
|
1648
1636
|
// ( '> -10' => '> -100' will ignore hidden rows )
|
1649
|
-
!(
|
1637
|
+
!( tsfRegex.isNeg1.test( val ) || tsfRegex.isNeg2.test( val ) ) &&
|
1650
1638
|
// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
|
1651
1639
|
!( val !== '' && c.$filters && c.$filters.filter( '[data-column="' + indx + '"]' ).find( 'select' ).length &&
|
1652
1640
|
!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
|
@@ -1664,7 +1652,7 @@
|
|
1664
1652
|
// replace accents
|
1665
1653
|
data.anyMatchFilter = ts.replaceAccents( data.anyMatchFilter );
|
1666
1654
|
}
|
1667
|
-
if ( wo.filter_defaultFilter &&
|
1655
|
+
if ( wo.filter_defaultFilter && tsfRegex.iQuery.test( vars.defaultAnyFilter ) ) {
|
1668
1656
|
data.anyMatchFilter = tsf.defaultFilter( data.anyMatchFilter, vars.defaultAnyFilter );
|
1669
1657
|
// clear search filtered flag because default filters are not saved to the last search
|
1670
1658
|
searchFiltered = false;
|
@@ -1681,9 +1669,9 @@
|
|
1681
1669
|
|
1682
1670
|
txt = $rows[ rowIndex ].className;
|
1683
1671
|
// the first row can never be a child row
|
1684
|
-
isChild = rowIndex &&
|
1672
|
+
isChild = rowIndex && tsfRegex.child.test( txt );
|
1685
1673
|
// skip child rows & already filtered rows
|
1686
|
-
if ( isChild || ( searchFiltered &&
|
1674
|
+
if ( isChild || ( searchFiltered && tsfRegex.filtered.test( txt ) ) ) {
|
1687
1675
|
continue;
|
1688
1676
|
}
|
1689
1677
|
|
@@ -1793,7 +1781,6 @@
|
|
1793
1781
|
// custom select source function for a SPECIFIC COLUMN
|
1794
1782
|
arry = fxn( table, column, onlyAvail );
|
1795
1783
|
}
|
1796
|
-
|
1797
1784
|
if ( arry === false ) {
|
1798
1785
|
// fall back to original method
|
1799
1786
|
arry = tsf.getOptions( table, column, onlyAvail );
|
@@ -1807,18 +1794,19 @@
|
|
1807
1794
|
return false;
|
1808
1795
|
}
|
1809
1796
|
table = $( table )[0];
|
1810
|
-
var cts, txt, indx, len,
|
1797
|
+
var cts, txt, indx, len, parsedTxt, str,
|
1811
1798
|
c = table.config,
|
1812
1799
|
validColumn = typeof column !== 'undefined' && column !== null && column >= 0 && column < c.columns,
|
1813
1800
|
parsed = [];
|
1814
|
-
|
1815
1801
|
// get unique elements and sort the list
|
1816
1802
|
// if $.tablesorter.sortText exists ( not in the original tablesorter ),
|
1817
1803
|
// then natural sort the list otherwise use a basic sort
|
1818
1804
|
arry = $.grep( arry, function( value, indx ) {
|
1805
|
+
if ( value.text ) {
|
1806
|
+
return true;
|
1807
|
+
}
|
1819
1808
|
return $.inArray( value, arry ) === indx;
|
1820
1809
|
});
|
1821
|
-
|
1822
1810
|
if ( validColumn && c.$headerIndexed[ column ].hasClass( 'filter-select-nosort' ) ) {
|
1823
1811
|
// unsorted select options
|
1824
1812
|
return arry;
|
@@ -1827,22 +1815,30 @@
|
|
1827
1815
|
// parse select option values
|
1828
1816
|
for ( indx = 0; indx < len; indx++ ) {
|
1829
1817
|
txt = arry[ indx ];
|
1818
|
+
// check for object
|
1819
|
+
str = txt.text ? txt.text : txt;
|
1820
|
+
// sortNatural breaks if you don't pass it strings
|
1821
|
+
parsedTxt = ( validColumn && c.parsers && c.parsers.length &&
|
1822
|
+
c.parsers[ column ].format( str, table, [], column ) || str ).toString();
|
1823
|
+
parsedTxt = c.widgetOptions.filter_ignoreCase ? parsedTxt.toLowerCase() : parsedTxt;
|
1830
1824
|
// parse array data using set column parser; this DOES NOT pass the original
|
1831
1825
|
// table cell to the parser format function
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1826
|
+
if ( txt.text ) {
|
1827
|
+
txt.parsed = parsedTxt;
|
1828
|
+
parsed.push( txt );
|
1829
|
+
} else {
|
1830
|
+
parsed.push({
|
1831
|
+
text : txt,
|
1832
|
+
// check parser length - fixes #934
|
1833
|
+
parsed : parsedTxt
|
1834
|
+
});
|
1835
|
+
}
|
1838
1836
|
}
|
1839
|
-
|
1840
1837
|
// sort parsed select options
|
1841
1838
|
cts = c.textSorter || '';
|
1842
1839
|
parsed.sort( function( a, b ) {
|
1843
|
-
|
1844
|
-
|
1845
|
-
y = b.p.toString();
|
1840
|
+
var x = a.parsed,
|
1841
|
+
y = b.parsed;
|
1846
1842
|
if ( validColumn && typeof cts === 'function' ) {
|
1847
1843
|
// custom OVERALL text sorter
|
1848
1844
|
return cts( x, y, true, column, table );
|
@@ -1860,7 +1856,7 @@
|
|
1860
1856
|
arry = [];
|
1861
1857
|
len = parsed.length;
|
1862
1858
|
for ( indx = 0; indx < len; indx++ ) {
|
1863
|
-
arry.push( parsed[indx]
|
1859
|
+
arry.push( parsed[indx] );
|
1864
1860
|
}
|
1865
1861
|
return arry;
|
1866
1862
|
}
|
@@ -1920,7 +1916,7 @@
|
|
1920
1916
|
return;
|
1921
1917
|
}
|
1922
1918
|
|
1923
|
-
var indx, val, txt, t, $filters, $filter,
|
1919
|
+
var indx, val, txt, t, $filters, $filter, option,
|
1924
1920
|
c = table.config,
|
1925
1921
|
wo = c.widgetOptions,
|
1926
1922
|
node = c.$headerIndexed[ column ],
|
@@ -1945,23 +1941,45 @@
|
|
1945
1941
|
if ( $.isArray( arry ) ) {
|
1946
1942
|
// build option list
|
1947
1943
|
for ( indx = 0; indx < arry.length; indx++ ) {
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1944
|
+
option = arry[ indx ];
|
1945
|
+
if ( option.text ) {
|
1946
|
+
// OBJECT!! add data-function-name in case the value is set in filter_functions
|
1947
|
+
option['data-function-name'] = typeof option.value === 'undefined' ? option.text : option.value;
|
1948
|
+
|
1949
|
+
// support jQuery < v1.8, otherwise the below code could be shortened to
|
1950
|
+
// options += $( '<option>', option )[ 0 ].outerHTML;
|
1951
|
+
options += '<option';
|
1952
|
+
for ( val in option ) {
|
1953
|
+
if ( option.hasOwnProperty( val ) && val !== 'text' ) {
|
1954
|
+
options += ' ' + val + '="' + option[ val ] + '"';
|
1955
|
+
}
|
1956
|
+
}
|
1957
|
+
if ( !option.value ) {
|
1958
|
+
options += ' value="' + option.text + '"';
|
1959
|
+
}
|
1960
|
+
options += '>' + option.text + '</option>';
|
1961
|
+
// above code is needed in jQuery < v1.8
|
1962
|
+
|
1963
|
+
// make sure we don't turn an object into a string (objects without a "text" property)
|
1964
|
+
} else if ( '' + option !== '[object Object]' ) {
|
1965
|
+
txt = option = ( '' + option ).replace( tsfRegex.quote, '"' );
|
1966
|
+
val = txt;
|
1967
|
+
// allow including a symbol in the selectSource array
|
1968
|
+
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
1969
|
+
// and 'A through Z' becomes the option text
|
1970
|
+
if ( txt.indexOf( wo.filter_selectSourceSeparator ) >= 0 ) {
|
1971
|
+
t = txt.split( wo.filter_selectSourceSeparator );
|
1972
|
+
val = t[0];
|
1973
|
+
txt = t[1];
|
1974
|
+
}
|
1975
|
+
// replace quotes - fixes #242 & ignore empty strings
|
1976
|
+
// see http://stackoverflow.com/q/14990971/145346
|
1977
|
+
options += option !== '' ?
|
1978
|
+
'<option ' +
|
1979
|
+
( val === txt ? '' : 'data-function-name="' + option + '" ' ) +
|
1980
|
+
'value="' + val + '">' + txt +
|
1981
|
+
'</option>' : '';
|
1957
1982
|
}
|
1958
|
-
// replace quotes - fixes #242 & ignore empty strings
|
1959
|
-
// see http://stackoverflow.com/q/14990971/145346
|
1960
|
-
options += arry[indx] !== '' ?
|
1961
|
-
'<option ' +
|
1962
|
-
( val === txt ? '' : 'data-function-name="' + arry[indx] + '" ' ) +
|
1963
|
-
'value="' + val + '">' + txt +
|
1964
|
-
'</option>' : '';
|
1965
1983
|
}
|
1966
1984
|
// clear arry so it doesn't get appended twice
|
1967
1985
|
arry = [];
|
@@ -2007,6 +2025,9 @@
|
|
2007
2025
|
}
|
2008
2026
|
};
|
2009
2027
|
|
2028
|
+
// filter regex variable
|
2029
|
+
tsfRegex = tsf.regex;
|
2030
|
+
|
2010
2031
|
ts.getFilters = function( table, getRaw, setFilters, skipFirst ) {
|
2011
2032
|
var i, $filters, $column, cols,
|
2012
2033
|
filters = false,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Parser: filetype *//*
|
1
|
+
/*! Parser: filetype - updated 11/10/2015 (v2.24.4) *//*
|
2
2
|
* When a file type extension is found, the equivalent name is
|
3
3
|
* prefixed into the parsed data, so sorting occurs in groups
|
4
4
|
*/
|
@@ -43,6 +43,7 @@
|
|
43
43
|
var t,
|
44
44
|
c = table.config,
|
45
45
|
wo = c.widgetOptions,
|
46
|
+
groupSeparator = wo.group_separator || '-',
|
46
47
|
i = s.lastIndexOf('.'),
|
47
48
|
sep = $.tablesorter.fileTypes.separator,
|
48
49
|
m = $.tablesorter.fileTypes.matching,
|
@@ -60,7 +61,8 @@
|
|
60
61
|
if (m.indexOf(t) >= 0) {
|
61
62
|
for (i in types) {
|
62
63
|
if ((sep + types[i] + sep).indexOf(t) >= 0) {
|
63
|
-
|
64
|
+
// groupSeparator may use a regular expression!
|
65
|
+
return i + ( groupSeparator.toString().charAt(0) !== '/' ? wo.group_separator : '-' ) + s;
|
64
66
|
}
|
65
67
|
}
|
66
68
|
}
|
@@ -70,4 +72,24 @@
|
|
70
72
|
type: 'text'
|
71
73
|
});
|
72
74
|
|
75
|
+
// sort by file extension
|
76
|
+
// converts "this.is.an.image.jpg" into "jpg.this.is.an.image"
|
77
|
+
$.tablesorter.addParser({
|
78
|
+
id: 'file-extension',
|
79
|
+
is: function() {
|
80
|
+
return false;
|
81
|
+
},
|
82
|
+
format: function( str ) {
|
83
|
+
var ext,
|
84
|
+
parts = str.split( '.' );
|
85
|
+
if ( parts.length ) {
|
86
|
+
ext = parts.pop();
|
87
|
+
parts.unshift( ext );
|
88
|
+
return parts.join( '.' );
|
89
|
+
}
|
90
|
+
return str;
|
91
|
+
},
|
92
|
+
type: 'text'
|
93
|
+
});
|
94
|
+
|
73
95
|
})(jQuery);
|