jquery-tablesorter 1.19.1 → 1.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +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);
|