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) {
|
@@ -16,7 +16,7 @@
|
|
16
16
|
}
|
17
17
|
}(function($) {
|
18
18
|
|
19
|
-
/*! TableSorter (FORK) v2.24.
|
19
|
+
/*! TableSorter (FORK) v2.24.4 *//*
|
20
20
|
* Client-side table sorting with ease!
|
21
21
|
* @requires jQuery v1.2.6+
|
22
22
|
*
|
@@ -39,7 +39,7 @@
|
|
39
39
|
'use strict';
|
40
40
|
var ts = $.tablesorter = {
|
41
41
|
|
42
|
-
version : '2.24.
|
42
|
+
version : '2.24.4',
|
43
43
|
|
44
44
|
parsers : [],
|
45
45
|
widgets : [],
|
@@ -157,12 +157,13 @@
|
|
157
157
|
|
158
158
|
// labels applied to sortable headers for accessibility (aria) support
|
159
159
|
language : {
|
160
|
-
sortAsc
|
161
|
-
sortDesc
|
162
|
-
sortNone
|
163
|
-
|
164
|
-
|
165
|
-
|
160
|
+
sortAsc : 'Ascending sort applied, ',
|
161
|
+
sortDesc : 'Descending sort applied, ',
|
162
|
+
sortNone : 'No sort applied, ',
|
163
|
+
sortDisabled : 'sorting is disabled',
|
164
|
+
nextAsc : 'activate to apply an ascending sort',
|
165
|
+
nextDesc : 'activate to apply a descending sort',
|
166
|
+
nextNone : 'activate to remove the sort'
|
166
167
|
},
|
167
168
|
|
168
169
|
regex : {
|
@@ -1011,7 +1012,7 @@
|
|
1011
1012
|
▀████▀ ██ █████▀ ██ ██ ██ ██████
|
1012
1013
|
*/
|
1013
1014
|
setHeadersCss : function( c ) {
|
1014
|
-
var $sorted,
|
1015
|
+
var $sorted, indx, column,
|
1015
1016
|
list = c.sortList,
|
1016
1017
|
len = list.length,
|
1017
1018
|
none = ts.css.sortNone + ' ' + c.cssNone,
|
@@ -1079,50 +1080,62 @@
|
|
1079
1080
|
}
|
1080
1081
|
// add verbose aria labels
|
1081
1082
|
len = c.$headers.length;
|
1082
|
-
$headers = c.$headers.not( '.sorter-false' );
|
1083
1083
|
for ( indx = 0; indx < len; indx++ ) {
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1084
|
+
ts.setColumnAriaLabel( c, c.$headers.eq( indx ) );
|
1085
|
+
}
|
1086
|
+
},
|
1087
|
+
|
1088
|
+
// nextSort (optional), lets you disable next sort text
|
1089
|
+
setColumnAriaLabel : function( c, $header, nextSort ) {
|
1090
|
+
if ( $header.length ) {
|
1091
|
+
var column = parseInt( $header.attr( 'data-column' ), 10 ),
|
1089
1092
|
tmp = $header.hasClass( ts.css.sortAsc ) ?
|
1090
1093
|
'sortAsc' :
|
1091
|
-
$header.hasClass( ts.css.sortDesc ) ? 'sortDesc' : 'sortNone'
|
1092
|
-
txt = $.trim( $header.text() ) + ': ' +
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1094
|
+
$header.hasClass( ts.css.sortDesc ) ? 'sortDesc' : 'sortNone',
|
1095
|
+
txt = $.trim( $header.text() ) + ': ' + ts.language[ tmp ];
|
1096
|
+
if ( $header.hasClass( 'sorter-false' ) || nextSort === false ) {
|
1097
|
+
txt += ts.language.sortDisabled;
|
1098
|
+
} else {
|
1099
|
+
nextSort = c.sortVars[ column ].order[ ( c.sortVars[ column ].count + 1 ) % ( c.sortReset ? 3 : 2 ) ];
|
1100
|
+
// if nextSort
|
1101
|
+
txt += ts.language[ nextSort === 0 ? 'nextAsc' : nextSort === 1 ? 'nextDesc' : 'nextNone' ];
|
1096
1102
|
}
|
1103
|
+
$header.attr( 'aria-label', txt );
|
1097
1104
|
}
|
1098
1105
|
},
|
1099
1106
|
|
1100
1107
|
updateHeader : function( c ) {
|
1101
|
-
var index, isDisabled, $
|
1108
|
+
var index, isDisabled, $header, col,
|
1102
1109
|
table = c.table,
|
1103
1110
|
len = c.$headers.length;
|
1104
1111
|
for ( index = 0; index < len; index++ ) {
|
1105
|
-
$
|
1112
|
+
$header = c.$headers.eq( index );
|
1106
1113
|
col = ts.getColumnData( table, c.headers, index, true );
|
1107
1114
|
// add 'sorter-false' class if 'parser-false' is set
|
1108
|
-
isDisabled = ts.getData( $
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1115
|
+
isDisabled = ts.getData( $header, col, 'sorter' ) === 'false' || ts.getData( $header, col, 'parser' ) === 'false';
|
1116
|
+
ts.setColumnSort( c, $header, isDisabled );
|
1117
|
+
}
|
1118
|
+
},
|
1119
|
+
|
1120
|
+
setColumnSort : function( c, $header, isDisabled ) {
|
1121
|
+
var id = c.table.id;
|
1122
|
+
$header[ 0 ].sortDisabled = isDisabled;
|
1123
|
+
$header[ isDisabled ? 'addClass' : 'removeClass' ]( 'sorter-false' )
|
1124
|
+
.attr( 'aria-disabled', '' + isDisabled );
|
1125
|
+
// disable tab index on disabled cells
|
1126
|
+
if ( c.tabIndex ) {
|
1127
|
+
if ( isDisabled ) {
|
1128
|
+
$header.removeAttr( 'tabindex' );
|
1129
|
+
} else {
|
1130
|
+
$header.attr( 'tabindex', '0' );
|
1118
1131
|
}
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1132
|
+
}
|
1133
|
+
// aria-controls - requires table ID
|
1134
|
+
if ( id ) {
|
1135
|
+
if ( isDisabled ) {
|
1136
|
+
$header.removeAttr( 'aria-controls' );
|
1137
|
+
} else {
|
1138
|
+
$header.attr( 'aria-controls', id );
|
1126
1139
|
}
|
1127
1140
|
}
|
1128
1141
|
},
|
@@ -1420,13 +1433,12 @@
|
|
1420
1433
|
event[ c.sortResetKey ] ? 2 : ( c.sortVars[ col ].count + 1 ) % ( c.sortReset ? 3 : 2 );
|
1421
1434
|
// reset all sorts on non-current column - issue #30
|
1422
1435
|
if ( c.sortRestart ) {
|
1423
|
-
tmp = cell;
|
1424
1436
|
for ( headerIndx = 0; headerIndx < len; headerIndx++ ) {
|
1425
1437
|
$header = c.$headers.eq( headerIndx );
|
1438
|
+
tmp = parseInt( $header.attr( 'data-column' ), 10 );
|
1426
1439
|
// only reset counts on columns that weren't just clicked on and if not included in a multisort
|
1427
|
-
if ( $header
|
1428
|
-
|
1429
|
-
c.sortVars[ $header.attr( 'data-column' ) ].count = -1;
|
1440
|
+
if ( col !== tmp && ( notMultiSort || $header.hasClass( ts.css.sortNone ) ) ) {
|
1441
|
+
c.sortVars[ tmp ].count = -1;
|
1430
1442
|
}
|
1431
1443
|
}
|
1432
1444
|
}
|
@@ -2185,14 +2197,14 @@
|
|
2185
2197
|
|
2186
2198
|
// *** Process table ***
|
2187
2199
|
// add processing indicator
|
2188
|
-
isProcessing : function( $table, toggle, $
|
2200
|
+
isProcessing : function( $table, toggle, $headers ) {
|
2189
2201
|
$table = $( $table );
|
2190
2202
|
var c = $table[ 0 ].config,
|
2191
2203
|
// default to all headers
|
2192
|
-
$header = $
|
2204
|
+
$header = $headers || $table.find( '.' + ts.css.header );
|
2193
2205
|
if ( toggle ) {
|
2194
|
-
// don't use sortList if custom $
|
2195
|
-
if ( typeof $
|
2206
|
+
// don't use sortList if custom $headers used
|
2207
|
+
if ( typeof $headers !== 'undefined' && c.sortList.length > 0 ) {
|
2196
2208
|
// get headers from the sortList
|
2197
2209
|
$header = $header.filter( function() {
|
2198
2210
|
// get data-column from attr to keep compatibility with jQuery 1.2.6
|
@@ -2984,13 +2996,13 @@
|
|
2984
2996
|
|
2985
2997
|
})(jQuery);
|
2986
2998
|
|
2987
|
-
/*! Widget: filter - updated 11/
|
2999
|
+
/*! Widget: filter - updated 11/10/2015 (v2.24.4) *//*
|
2988
3000
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
2989
3001
|
* by Rob Garrison
|
2990
3002
|
*/
|
2991
3003
|
;( function ( $ ) {
|
2992
3004
|
'use strict';
|
2993
|
-
var tsf,
|
3005
|
+
var tsf, tsfRegex,
|
2994
3006
|
ts = $.tablesorter || {},
|
2995
3007
|
tscss = ts.css;
|
2996
3008
|
|
@@ -3096,20 +3108,21 @@
|
|
3096
3108
|
// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
|
3097
3109
|
types: {
|
3098
3110
|
or : function( c, data, vars ) {
|
3099
|
-
|
3111
|
+
// look for "|", but not if it is inside of a regular expression
|
3112
|
+
if ( ( tsfRegex.orTest.test( data.iFilter ) || tsfRegex.orSplit.test( data.filter ) ) &&
|
3113
|
+
// this test for regex has potential to slow down the overall search
|
3114
|
+
!tsfRegex.regex.test( data.filter ) ) {
|
3100
3115
|
var indx, filterMatched, query, regex,
|
3101
3116
|
// duplicate data but split filter
|
3102
3117
|
data2 = $.extend( {}, data ),
|
3103
|
-
|
3104
|
-
|
3105
|
-
filter = data.filter.split( tsf.regex.orSplit ),
|
3106
|
-
iFilter = data.iFilter.split( tsf.regex.orSplit ),
|
3118
|
+
filter = data.filter.split( tsfRegex.orSplit ),
|
3119
|
+
iFilter = data.iFilter.split( tsfRegex.orSplit ),
|
3107
3120
|
len = filter.length;
|
3108
3121
|
for ( indx = 0; indx < len; indx++ ) {
|
3109
3122
|
data2.nestedFilters = true;
|
3110
|
-
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ],
|
3111
|
-
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ],
|
3112
|
-
query = '(' + ( tsf.parseFilter( c, data2.filter,
|
3123
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], data ) || '' );
|
3124
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], data ) || '' );
|
3125
|
+
query = '(' + ( tsf.parseFilter( c, data2.filter, data ) || '' ) + ')';
|
3113
3126
|
try {
|
3114
3127
|
// use try/catch, because query may not be a valid regex if "|" is contained within a partial regex search,
|
3115
3128
|
// e.g "/(Alex|Aar" -> Uncaught SyntaxError: Invalid regular expression: /(/(Alex)/: Unterminated group
|
@@ -3131,22 +3144,20 @@
|
|
3131
3144
|
},
|
3132
3145
|
// Look for an AND or && operator ( logical and )
|
3133
3146
|
and : function( c, data, vars ) {
|
3134
|
-
if (
|
3147
|
+
if ( tsfRegex.andTest.test( data.filter ) ) {
|
3135
3148
|
var indx, filterMatched, result, query, regex,
|
3136
3149
|
// duplicate data but split filter
|
3137
3150
|
data2 = $.extend( {}, data ),
|
3138
|
-
|
3139
|
-
|
3140
|
-
filter = data.filter.split( tsf.regex.andSplit ),
|
3141
|
-
iFilter = data.iFilter.split( tsf.regex.andSplit ),
|
3151
|
+
filter = data.filter.split( tsfRegex.andSplit ),
|
3152
|
+
iFilter = data.iFilter.split( tsfRegex.andSplit ),
|
3142
3153
|
len = filter.length;
|
3143
3154
|
for ( indx = 0; indx < len; indx++ ) {
|
3144
3155
|
data2.nestedFilters = true;
|
3145
|
-
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ],
|
3146
|
-
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ],
|
3147
|
-
query = ( '(' + ( tsf.parseFilter( c, data2.filter,
|
3156
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], data ) || '' );
|
3157
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], data ) || '' );
|
3158
|
+
query = ( '(' + ( tsf.parseFilter( c, data2.filter, data ) || '' ) + ')' )
|
3148
3159
|
// replace wild cards since /(a*)/i will match anything
|
3149
|
-
.replace(
|
3160
|
+
.replace( tsfRegex.wild01, '\\S{1}' ).replace( tsfRegex.wild0More, '\\S*' );
|
3150
3161
|
try {
|
3151
3162
|
// use try/catch just in case RegExp is invalid
|
3152
3163
|
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
@@ -3168,10 +3179,10 @@
|
|
3168
3179
|
},
|
3169
3180
|
// Look for regex
|
3170
3181
|
regex: function( c, data ) {
|
3171
|
-
if (
|
3182
|
+
if ( tsfRegex.regex.test( data.filter ) ) {
|
3172
3183
|
var matches,
|
3173
3184
|
// cache regex per column for optimal speed
|
3174
|
-
regex = data.filter_regexCache[ data.index ] ||
|
3185
|
+
regex = data.filter_regexCache[ data.index ] || tsfRegex.regex.exec( data.filter ),
|
3175
3186
|
isRegex = regex instanceof RegExp;
|
3176
3187
|
try {
|
3177
3188
|
if ( !isRegex ) {
|
@@ -3190,18 +3201,17 @@
|
|
3190
3201
|
// Look for operators >, >=, < or <=
|
3191
3202
|
operators: function( c, data ) {
|
3192
3203
|
// ignore empty strings... because '' < 10 is true
|
3193
|
-
if (
|
3204
|
+
if ( tsfRegex.operTest.test( data.iFilter ) && data.iExact !== '' ) {
|
3194
3205
|
var cachedValue, result, txt,
|
3195
3206
|
table = c.table,
|
3196
|
-
|
3197
|
-
|
3198
|
-
|
3199
|
-
parser = c.parsers[index],
|
3207
|
+
parsed = data.parsed[ data.index ],
|
3208
|
+
query = ts.formatFloat( data.iFilter.replace( tsfRegex.operators, '' ), table ),
|
3209
|
+
parser = c.parsers[ data.index ],
|
3200
3210
|
savedSearch = query;
|
3201
3211
|
// parse filter value in case we're comparing numbers ( dates )
|
3202
3212
|
if ( parsed || parser.type === 'numeric' ) {
|
3203
|
-
txt = $.trim( '' + data.iFilter.replace(
|
3204
|
-
result = tsf.parseFilter( c, txt,
|
3213
|
+
txt = $.trim( '' + data.iFilter.replace( tsfRegex.operators, '' ) );
|
3214
|
+
result = tsf.parseFilter( c, txt, data, true );
|
3205
3215
|
query = ( typeof result === 'number' && result !== '' && !isNaN( result ) ) ? result : query;
|
3206
3216
|
}
|
3207
3217
|
// iExact may be numeric - see issue #149;
|
@@ -3213,10 +3223,10 @@
|
|
3213
3223
|
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
|
3214
3224
|
cachedValue = ts.formatFloat( txt, table );
|
3215
3225
|
}
|
3216
|
-
if (
|
3217
|
-
result =
|
3218
|
-
} else if (
|
3219
|
-
result =
|
3226
|
+
if ( tsfRegex.gtTest.test( data.iFilter ) ) {
|
3227
|
+
result = tsfRegex.gteTest.test( data.iFilter ) ? cachedValue >= query : cachedValue > query;
|
3228
|
+
} else if ( tsfRegex.ltTest.test( data.iFilter ) ) {
|
3229
|
+
result = tsfRegex.lteTest.test( data.iFilter ) ? cachedValue <= query : cachedValue < query;
|
3220
3230
|
}
|
3221
3231
|
// keep showing all rows if nothing follows the operator
|
3222
3232
|
if ( !result && savedSearch === '' ) {
|
@@ -3228,13 +3238,13 @@
|
|
3228
3238
|
},
|
3229
3239
|
// Look for a not match
|
3230
3240
|
notMatch: function( c, data ) {
|
3231
|
-
if (
|
3241
|
+
if ( tsfRegex.notTest.test( data.iFilter ) ) {
|
3232
3242
|
var indx,
|
3233
3243
|
txt = data.iFilter.replace( '!', '' ),
|
3234
|
-
filter = tsf.parseFilter( c, txt, data
|
3235
|
-
if (
|
3244
|
+
filter = tsf.parseFilter( c, txt, data ) || '';
|
3245
|
+
if ( tsfRegex.exact.test( filter ) ) {
|
3236
3246
|
// look for exact not matches - see #628
|
3237
|
-
filter = filter.replace(
|
3247
|
+
filter = filter.replace( tsfRegex.exact, '' );
|
3238
3248
|
return filter === '' ? true : $.trim( filter ) !== data.iExact;
|
3239
3249
|
} else {
|
3240
3250
|
indx = data.iExact.search( $.trim( filter ) );
|
@@ -3246,29 +3256,29 @@
|
|
3246
3256
|
// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
|
3247
3257
|
exact: function( c, data ) {
|
3248
3258
|
/*jshint eqeqeq:false */
|
3249
|
-
if (
|
3250
|
-
var txt = data.iFilter.replace(
|
3251
|
-
filter = tsf.parseFilter( c, txt, data
|
3259
|
+
if ( tsfRegex.exact.test( data.iFilter ) ) {
|
3260
|
+
var txt = data.iFilter.replace( tsfRegex.exact, '' ),
|
3261
|
+
filter = tsf.parseFilter( c, txt, data ) || '';
|
3252
3262
|
return data.anyMatch ? $.inArray( filter, data.rowArray ) >= 0 : filter == data.iExact;
|
3253
3263
|
}
|
3254
3264
|
return null;
|
3255
3265
|
},
|
3256
3266
|
// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
|
3257
3267
|
range : function( c, data ) {
|
3258
|
-
if (
|
3268
|
+
if ( tsfRegex.toTest.test( data.iFilter ) ) {
|
3259
3269
|
var result, tmp, range1, range2,
|
3260
3270
|
table = c.table,
|
3261
3271
|
index = data.index,
|
3262
3272
|
parsed = data.parsed[index],
|
3263
3273
|
// make sure the dash is for a range and not indicating a negative number
|
3264
|
-
query = data.iFilter.split(
|
3274
|
+
query = data.iFilter.split( tsfRegex.toSplit );
|
3265
3275
|
|
3266
3276
|
tmp = query[0].replace( ts.regex.nondigit, '' ) || '';
|
3267
|
-
range1 = ts.formatFloat( tsf.parseFilter( c, tmp,
|
3277
|
+
range1 = ts.formatFloat( tsf.parseFilter( c, tmp, data ), table );
|
3268
3278
|
tmp = query[1].replace( ts.regex.nondigit, '' ) || '';
|
3269
|
-
range2 = ts.formatFloat( tsf.parseFilter( c, tmp,
|
3279
|
+
range2 = ts.formatFloat( tsf.parseFilter( c, tmp, data ), table );
|
3270
3280
|
// parse filter value in case we're comparing numbers ( dates )
|
3271
|
-
if ( parsed || c.parsers[index].type === 'numeric' ) {
|
3281
|
+
if ( parsed || c.parsers[ index ].type === 'numeric' ) {
|
3272
3282
|
result = c.parsers[ index ].format( '' + query[0], table, c.$headers.eq( index ), index );
|
3273
3283
|
range1 = ( result !== '' && !isNaN( result ) ) ? result : range1;
|
3274
3284
|
result = c.parsers[ index ].format( '' + query[1], table, c.$headers.eq( index ), index );
|
@@ -3289,18 +3299,16 @@
|
|
3289
3299
|
},
|
3290
3300
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
3291
3301
|
wild : function( c, data ) {
|
3292
|
-
if (
|
3293
|
-
var
|
3294
|
-
parsed = data.parsed[ index ],
|
3295
|
-
query = '' + ( tsf.parseFilter( c, data.iFilter, index, parsed ) || '' );
|
3302
|
+
if ( tsfRegex.wildOrTest.test( data.iFilter ) ) {
|
3303
|
+
var query = '' + ( tsf.parseFilter( c, data.iFilter, data ) || '' );
|
3296
3304
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
3297
|
-
if ( !
|
3305
|
+
if ( !tsfRegex.wildTest.test( query ) && data.nestedFilters ) {
|
3298
3306
|
query = data.isMatch ? query : '^(' + query + ')$';
|
3299
3307
|
}
|
3300
3308
|
// parsing the filter may not work properly when using wildcards =/
|
3301
3309
|
try {
|
3302
3310
|
return new RegExp(
|
3303
|
-
query.replace(
|
3311
|
+
query.replace( tsfRegex.wild01, '\\S{1}' ).replace( tsfRegex.wild0More, '\\S*' ),
|
3304
3312
|
c.widgetOptions.filter_ignoreCase ? 'i' : ''
|
3305
3313
|
)
|
3306
3314
|
.test( data.exact );
|
@@ -3312,21 +3320,18 @@
|
|
3312
3320
|
},
|
3313
3321
|
// fuzzy text search; modified from https://github.com/mattyork/fuzzy ( MIT license )
|
3314
3322
|
fuzzy: function( c, data ) {
|
3315
|
-
if (
|
3323
|
+
if ( tsfRegex.fuzzyTest.test( data.iFilter ) ) {
|
3316
3324
|
var indx,
|
3317
3325
|
patternIndx = 0,
|
3318
3326
|
len = data.iExact.length,
|
3319
3327
|
txt = data.iFilter.slice( 1 ),
|
3320
|
-
pattern = tsf.parseFilter( c, txt, data
|
3328
|
+
pattern = tsf.parseFilter( c, txt, data ) || '';
|
3321
3329
|
for ( indx = 0; indx < len; indx++ ) {
|
3322
3330
|
if ( data.iExact[ indx ] === pattern[ patternIndx ] ) {
|
3323
3331
|
patternIndx += 1;
|
3324
3332
|
}
|
3325
3333
|
}
|
3326
|
-
|
3327
|
-
return true;
|
3328
|
-
}
|
3329
|
-
return false;
|
3334
|
+
return patternIndx === pattern.length;
|
3330
3335
|
}
|
3331
3336
|
return null;
|
3332
3337
|
}
|
@@ -3339,8 +3344,7 @@
|
|
3339
3344
|
and : 'and'
|
3340
3345
|
}, ts.language );
|
3341
3346
|
|
3342
|
-
var options, string, txt, $header, column, filters, val, fxn, noSelect
|
3343
|
-
regex = tsf.regex;
|
3347
|
+
var options, string, txt, $header, column, filters, val, fxn, noSelect;
|
3344
3348
|
c.$table.addClass( 'hasFilters' );
|
3345
3349
|
|
3346
3350
|
// define timers so using clearTimeout won't cause an undefined error
|
@@ -3351,8 +3355,8 @@
|
|
3351
3355
|
wo.filter_anyColumnSelector = '[data-column="all"],[data-column="any"]';
|
3352
3356
|
wo.filter_multipleColumnSelector = '[data-column*="-"],[data-column*=","]';
|
3353
3357
|
|
3354
|
-
val = '\\{' +
|
3355
|
-
$.extend(
|
3358
|
+
val = '\\{' + tsfRegex.query + '\\}';
|
3359
|
+
$.extend( tsfRegex, {
|
3356
3360
|
child : new RegExp( c.cssChildRow ),
|
3357
3361
|
filtered : new RegExp( wo.filter_filteredRow ),
|
3358
3362
|
alreadyFiltered : new RegExp( '(\\s+(' + ts.language.or + '|-|' + ts.language.to + ')\\s+)', 'i' ),
|
@@ -3630,8 +3634,10 @@
|
|
3630
3634
|
c.$table.data( 'lastSearch', filters );
|
3631
3635
|
return filters;
|
3632
3636
|
},
|
3633
|
-
parseFilter: function( c, filter,
|
3634
|
-
return parsed
|
3637
|
+
parseFilter: function( c, filter, data, parsed ) {
|
3638
|
+
return parsed || data.parsed[ data.index ] ?
|
3639
|
+
c.parsers[ data.index ].format( filter, c.table, [], data.index ) :
|
3640
|
+
filter;
|
3635
3641
|
},
|
3636
3642
|
buildRow: function( table, c, wo ) {
|
3637
3643
|
var $filter, col, column, $header, makeSelect, disabled, name, ffxn, tmp,
|
@@ -3824,8 +3830,12 @@
|
|
3824
3830
|
c.lastCombinedFilter = null;
|
3825
3831
|
c.lastSearch = [];
|
3826
3832
|
}
|
3827
|
-
// convert filters to strings
|
3828
|
-
filters =
|
3833
|
+
// convert filters to strings - see #1070
|
3834
|
+
filters = Array.prototype.map ?
|
3835
|
+
filters.map( String ) :
|
3836
|
+
// for IE8 & older browsers - maybe not the best method
|
3837
|
+
filters.join( '\u0000' ).split( '\u0000' );
|
3838
|
+
|
3829
3839
|
if ( wo.filter_initialized ) {
|
3830
3840
|
c.$table.trigger( 'filterStart', [ filters ] );
|
3831
3841
|
}
|
@@ -3879,8 +3889,8 @@
|
|
3879
3889
|
},
|
3880
3890
|
defaultFilter: function( filter, mask ) {
|
3881
3891
|
if ( filter === '' ) { return filter; }
|
3882
|
-
var regex =
|
3883
|
-
maskLen = mask.match(
|
3892
|
+
var regex = tsfRegex.iQuery,
|
3893
|
+
maskLen = mask.match( tsfRegex.igQuery ).length,
|
3884
3894
|
query = maskLen > 1 ? $.trim( filter ).split( /\s/ ) : [ $.trim( filter ) ],
|
3885
3895
|
len = query.length - 1,
|
3886
3896
|
indx = 0,
|
@@ -3977,9 +3987,8 @@
|
|
3977
3987
|
return filterMatched;
|
3978
3988
|
},
|
3979
3989
|
processRow: function( c, data, vars ) {
|
3980
|
-
var
|
3990
|
+
var result, filterMatched,
|
3981
3991
|
fxn, ffxn, txt,
|
3982
|
-
regex = tsf.regex,
|
3983
3992
|
wo = c.widgetOptions,
|
3984
3993
|
showRow = true,
|
3985
3994
|
|
@@ -4058,7 +4067,7 @@
|
|
4058
4067
|
result = data.rawArray[ columnIndex ] || '';
|
4059
4068
|
data.exact = c.sortLocaleCompare ? ts.replaceAccents( result ) : result; // issue #405
|
4060
4069
|
}
|
4061
|
-
data.iExact = !
|
4070
|
+
data.iExact = !tsfRegex.type.test( typeof data.exact ) && wo.filter_ignoreCase ?
|
4062
4071
|
data.exact.toLowerCase() : data.exact;
|
4063
4072
|
|
4064
4073
|
data.isMatch = c.$headerIndexed[ data.index ].hasClass( 'filter-match' );
|
@@ -4076,21 +4085,13 @@
|
|
4076
4085
|
data.filter = ts.replaceAccents( data.filter );
|
4077
4086
|
}
|
4078
4087
|
|
4079
|
-
val = true;
|
4080
|
-
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
4081
|
-
data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
4082
|
-
// val is used to indicate that a filter select is using a default filter;
|
4083
|
-
// so we override the exact & partial matches
|
4084
|
-
val = false;
|
4085
|
-
}
|
4086
4088
|
// data.iFilter = case insensitive ( if wo.filter_ignoreCase is true ),
|
4087
4089
|
// data.filter = case sensitive
|
4088
4090
|
data.iFilter = wo.filter_ignoreCase ? ( data.filter || '' ).toLowerCase() : data.filter;
|
4089
4091
|
fxn = vars.functions[ columnIndex ];
|
4090
|
-
hasSelect = c.$headerIndexed[ columnIndex ].hasClass( 'filter-select' );
|
4091
4092
|
filterMatched = null;
|
4092
|
-
if ( fxn
|
4093
|
-
if ( fxn === true
|
4093
|
+
if ( fxn ) {
|
4094
|
+
if ( fxn === true ) {
|
4094
4095
|
// default selector uses exact match unless 'filter-match' class is found
|
4095
4096
|
filterMatched = data.isMatch ?
|
4096
4097
|
// data.iExact may be a number
|
@@ -4116,7 +4117,7 @@
|
|
4116
4117
|
// Look for match, and add child row data for matching
|
4117
4118
|
} else {
|
4118
4119
|
txt = ( data.iExact + data.childRowText )
|
4119
|
-
.indexOf( tsf.parseFilter( c, data.iFilter,
|
4120
|
+
.indexOf( tsf.parseFilter( c, data.iFilter, data ) );
|
4120
4121
|
result = ( ( !wo.filter_startsWith && txt >= 0 ) || ( wo.filter_startsWith && txt === 0 ) );
|
4121
4122
|
}
|
4122
4123
|
} else {
|
@@ -4136,7 +4137,6 @@
|
|
4136
4137
|
isChild, childRow, lastSearch, showRow, showParent, time, val, indx,
|
4137
4138
|
notFiltered, searchFiltered, query, injected, res, id, txt,
|
4138
4139
|
storedFilters = $.extend( [], filters ),
|
4139
|
-
regex = tsf.regex,
|
4140
4140
|
c = table.config,
|
4141
4141
|
wo = c.widgetOptions,
|
4142
4142
|
// data object passed to filters; anyMatch is a flag for the filters
|
@@ -4218,7 +4218,7 @@
|
|
4218
4218
|
);
|
4219
4219
|
if ( wo.filter_columnAnyMatch ) {
|
4220
4220
|
// specific columns search
|
4221
|
-
query = data.anyMatchFilter.split(
|
4221
|
+
query = data.anyMatchFilter.split( tsfRegex.andSplit );
|
4222
4222
|
injected = false;
|
4223
4223
|
for ( indx = 0; indx < query.length; indx++ ) {
|
4224
4224
|
res = query[ indx ].split( ':' );
|
@@ -4253,12 +4253,12 @@
|
|
4253
4253
|
// there are no changes from beginning of filter
|
4254
4254
|
val.indexOf( lastSearch[indx] || '' ) === 0 &&
|
4255
4255
|
// if there is NOT a logical 'or', or range ( 'to' or '-' ) in the string
|
4256
|
-
!
|
4256
|
+
!tsfRegex.alreadyFiltered.test( val ) &&
|
4257
4257
|
// if we are not doing exact matches, using '|' ( logical or ) or not '!'
|
4258
|
-
!
|
4258
|
+
!tsfRegex.exactTest.test( val ) &&
|
4259
4259
|
// don't search only filtered if the value is negative
|
4260
4260
|
// ( '> -10' => '> -100' will ignore hidden rows )
|
4261
|
-
!(
|
4261
|
+
!( tsfRegex.isNeg1.test( val ) || tsfRegex.isNeg2.test( val ) ) &&
|
4262
4262
|
// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
|
4263
4263
|
!( val !== '' && c.$filters && c.$filters.filter( '[data-column="' + indx + '"]' ).find( 'select' ).length &&
|
4264
4264
|
!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
|
@@ -4276,7 +4276,7 @@
|
|
4276
4276
|
// replace accents
|
4277
4277
|
data.anyMatchFilter = ts.replaceAccents( data.anyMatchFilter );
|
4278
4278
|
}
|
4279
|
-
if ( wo.filter_defaultFilter &&
|
4279
|
+
if ( wo.filter_defaultFilter && tsfRegex.iQuery.test( vars.defaultAnyFilter ) ) {
|
4280
4280
|
data.anyMatchFilter = tsf.defaultFilter( data.anyMatchFilter, vars.defaultAnyFilter );
|
4281
4281
|
// clear search filtered flag because default filters are not saved to the last search
|
4282
4282
|
searchFiltered = false;
|
@@ -4293,9 +4293,9 @@
|
|
4293
4293
|
|
4294
4294
|
txt = $rows[ rowIndex ].className;
|
4295
4295
|
// the first row can never be a child row
|
4296
|
-
isChild = rowIndex &&
|
4296
|
+
isChild = rowIndex && tsfRegex.child.test( txt );
|
4297
4297
|
// skip child rows & already filtered rows
|
4298
|
-
if ( isChild || ( searchFiltered &&
|
4298
|
+
if ( isChild || ( searchFiltered && tsfRegex.filtered.test( txt ) ) ) {
|
4299
4299
|
continue;
|
4300
4300
|
}
|
4301
4301
|
|
@@ -4405,7 +4405,6 @@
|
|
4405
4405
|
// custom select source function for a SPECIFIC COLUMN
|
4406
4406
|
arry = fxn( table, column, onlyAvail );
|
4407
4407
|
}
|
4408
|
-
|
4409
4408
|
if ( arry === false ) {
|
4410
4409
|
// fall back to original method
|
4411
4410
|
arry = tsf.getOptions( table, column, onlyAvail );
|
@@ -4419,18 +4418,19 @@
|
|
4419
4418
|
return false;
|
4420
4419
|
}
|
4421
4420
|
table = $( table )[0];
|
4422
|
-
var cts, txt, indx, len,
|
4421
|
+
var cts, txt, indx, len, parsedTxt, str,
|
4423
4422
|
c = table.config,
|
4424
4423
|
validColumn = typeof column !== 'undefined' && column !== null && column >= 0 && column < c.columns,
|
4425
4424
|
parsed = [];
|
4426
|
-
|
4427
4425
|
// get unique elements and sort the list
|
4428
4426
|
// if $.tablesorter.sortText exists ( not in the original tablesorter ),
|
4429
4427
|
// then natural sort the list otherwise use a basic sort
|
4430
4428
|
arry = $.grep( arry, function( value, indx ) {
|
4429
|
+
if ( value.text ) {
|
4430
|
+
return true;
|
4431
|
+
}
|
4431
4432
|
return $.inArray( value, arry ) === indx;
|
4432
4433
|
});
|
4433
|
-
|
4434
4434
|
if ( validColumn && c.$headerIndexed[ column ].hasClass( 'filter-select-nosort' ) ) {
|
4435
4435
|
// unsorted select options
|
4436
4436
|
return arry;
|
@@ -4439,22 +4439,30 @@
|
|
4439
4439
|
// parse select option values
|
4440
4440
|
for ( indx = 0; indx < len; indx++ ) {
|
4441
4441
|
txt = arry[ indx ];
|
4442
|
+
// check for object
|
4443
|
+
str = txt.text ? txt.text : txt;
|
4444
|
+
// sortNatural breaks if you don't pass it strings
|
4445
|
+
parsedTxt = ( validColumn && c.parsers && c.parsers.length &&
|
4446
|
+
c.parsers[ column ].format( str, table, [], column ) || str ).toString();
|
4447
|
+
parsedTxt = c.widgetOptions.filter_ignoreCase ? parsedTxt.toLowerCase() : parsedTxt;
|
4442
4448
|
// parse array data using set column parser; this DOES NOT pass the original
|
4443
4449
|
// table cell to the parser format function
|
4444
|
-
|
4445
|
-
|
4446
|
-
|
4447
|
-
|
4448
|
-
|
4449
|
-
|
4450
|
+
if ( txt.text ) {
|
4451
|
+
txt.parsed = parsedTxt;
|
4452
|
+
parsed.push( txt );
|
4453
|
+
} else {
|
4454
|
+
parsed.push({
|
4455
|
+
text : txt,
|
4456
|
+
// check parser length - fixes #934
|
4457
|
+
parsed : parsedTxt
|
4458
|
+
});
|
4459
|
+
}
|
4450
4460
|
}
|
4451
|
-
|
4452
4461
|
// sort parsed select options
|
4453
4462
|
cts = c.textSorter || '';
|
4454
4463
|
parsed.sort( function( a, b ) {
|
4455
|
-
|
4456
|
-
|
4457
|
-
y = b.p.toString();
|
4464
|
+
var x = a.parsed,
|
4465
|
+
y = b.parsed;
|
4458
4466
|
if ( validColumn && typeof cts === 'function' ) {
|
4459
4467
|
// custom OVERALL text sorter
|
4460
4468
|
return cts( x, y, true, column, table );
|
@@ -4472,7 +4480,7 @@
|
|
4472
4480
|
arry = [];
|
4473
4481
|
len = parsed.length;
|
4474
4482
|
for ( indx = 0; indx < len; indx++ ) {
|
4475
|
-
arry.push( parsed[indx]
|
4483
|
+
arry.push( parsed[indx] );
|
4476
4484
|
}
|
4477
4485
|
return arry;
|
4478
4486
|
}
|
@@ -4532,7 +4540,7 @@
|
|
4532
4540
|
return;
|
4533
4541
|
}
|
4534
4542
|
|
4535
|
-
var indx, val, txt, t, $filters, $filter,
|
4543
|
+
var indx, val, txt, t, $filters, $filter, option,
|
4536
4544
|
c = table.config,
|
4537
4545
|
wo = c.widgetOptions,
|
4538
4546
|
node = c.$headerIndexed[ column ],
|
@@ -4557,23 +4565,45 @@
|
|
4557
4565
|
if ( $.isArray( arry ) ) {
|
4558
4566
|
// build option list
|
4559
4567
|
for ( indx = 0; indx < arry.length; indx++ ) {
|
4560
|
-
|
4561
|
-
|
4562
|
-
|
4563
|
-
|
4564
|
-
|
4565
|
-
|
4566
|
-
|
4567
|
-
|
4568
|
-
|
4568
|
+
option = arry[ indx ];
|
4569
|
+
if ( option.text ) {
|
4570
|
+
// OBJECT!! add data-function-name in case the value is set in filter_functions
|
4571
|
+
option['data-function-name'] = typeof option.value === 'undefined' ? option.text : option.value;
|
4572
|
+
|
4573
|
+
// support jQuery < v1.8, otherwise the below code could be shortened to
|
4574
|
+
// options += $( '<option>', option )[ 0 ].outerHTML;
|
4575
|
+
options += '<option';
|
4576
|
+
for ( val in option ) {
|
4577
|
+
if ( option.hasOwnProperty( val ) && val !== 'text' ) {
|
4578
|
+
options += ' ' + val + '="' + option[ val ] + '"';
|
4579
|
+
}
|
4580
|
+
}
|
4581
|
+
if ( !option.value ) {
|
4582
|
+
options += ' value="' + option.text + '"';
|
4583
|
+
}
|
4584
|
+
options += '>' + option.text + '</option>';
|
4585
|
+
// above code is needed in jQuery < v1.8
|
4586
|
+
|
4587
|
+
// make sure we don't turn an object into a string (objects without a "text" property)
|
4588
|
+
} else if ( '' + option !== '[object Object]' ) {
|
4589
|
+
txt = option = ( '' + option ).replace( tsfRegex.quote, '"' );
|
4590
|
+
val = txt;
|
4591
|
+
// allow including a symbol in the selectSource array
|
4592
|
+
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
4593
|
+
// and 'A through Z' becomes the option text
|
4594
|
+
if ( txt.indexOf( wo.filter_selectSourceSeparator ) >= 0 ) {
|
4595
|
+
t = txt.split( wo.filter_selectSourceSeparator );
|
4596
|
+
val = t[0];
|
4597
|
+
txt = t[1];
|
4598
|
+
}
|
4599
|
+
// replace quotes - fixes #242 & ignore empty strings
|
4600
|
+
// see http://stackoverflow.com/q/14990971/145346
|
4601
|
+
options += option !== '' ?
|
4602
|
+
'<option ' +
|
4603
|
+
( val === txt ? '' : 'data-function-name="' + option + '" ' ) +
|
4604
|
+
'value="' + val + '">' + txt +
|
4605
|
+
'</option>' : '';
|
4569
4606
|
}
|
4570
|
-
// replace quotes - fixes #242 & ignore empty strings
|
4571
|
-
// see http://stackoverflow.com/q/14990971/145346
|
4572
|
-
options += arry[indx] !== '' ?
|
4573
|
-
'<option ' +
|
4574
|
-
( val === txt ? '' : 'data-function-name="' + arry[indx] + '" ' ) +
|
4575
|
-
'value="' + val + '">' + txt +
|
4576
|
-
'</option>' : '';
|
4577
4607
|
}
|
4578
4608
|
// clear arry so it doesn't get appended twice
|
4579
4609
|
arry = [];
|
@@ -4619,6 +4649,9 @@
|
|
4619
4649
|
}
|
4620
4650
|
};
|
4621
4651
|
|
4652
|
+
// filter regex variable
|
4653
|
+
tsfRegex = tsf.regex;
|
4654
|
+
|
4622
4655
|
ts.getFilters = function( table, getRaw, setFilters, skipFirst ) {
|
4623
4656
|
var i, $filters, $column, cols,
|
4624
4657
|
filters = false,
|