jquery-tablesorter 1.18.1 → 1.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -4
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +218 -155
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +79 -43
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +139 -112
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +6 -4
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +138 -111
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 886efa143e551b3b1b348bfc4a5ceb244cba60d1
|
4
|
+
data.tar.gz: b3ae2ede803d0ef6014d497114a502a3128b4d27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a526f91f99c7d413b1d4c92b5b3ff03cb539bc4fda82e6f23cee1ffb162338b698b2c7ab91c5779fd824e52813f7eb4747e7dbd37ec7d9cc3f7d9f83cbb26d3
|
7
|
+
data.tar.gz: e42ae380bbddbca7bb6c7ccb74d2581cad6eb2d5273cd07f39bbd2ec804dec5ac2b8a63080b37e9eda3d236d8fdfd51c8fdb47dd19cf8cc6b4af7dbacddbe72f
|
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.23.
|
7
|
+
Current tablesorter version: 2.23.2 (8/23/2015), [documentation]
|
8
8
|
|
9
9
|
Any issue associated with the js/css files, please report to [Mottie's fork].
|
10
10
|
|
@@ -24,9 +24,8 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Requirements
|
26
26
|
|
27
|
-
Rails 3.2 and higher (tested up to 4.2)
|
28
|
-
|
29
|
-
Tested with ruby 1.9.3 - 2.2.2
|
27
|
+
It should work with Rails 3.2 and higher (tested up to 4.2) as well as with ruby 1.9.3 - 2.2.x.
|
28
|
+
Each release is always tested with the latest version of both.
|
30
29
|
|
31
30
|
## Usage
|
32
31
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀▀██
|
5
5
|
█████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
|
6
6
|
*/
|
7
|
-
/*! tablesorter (FORK) - updated 08-
|
7
|
+
/*! tablesorter (FORK) - updated 08-23-2015 (v2.23.2)*/
|
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.23.
|
19
|
+
/*! TableSorter (FORK) v2.23.2 *//*
|
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.23.
|
47
|
+
ts.version = '2.23.2';
|
48
48
|
|
49
49
|
ts.parsers = [];
|
50
50
|
ts.widgets = [];
|
@@ -169,6 +169,15 @@
|
|
169
169
|
nextNone : 'activate to remove the sort'
|
170
170
|
};
|
171
171
|
|
172
|
+
ts.regex = {
|
173
|
+
templateContent : /\{content\}/g,
|
174
|
+
templateIcon : /\{icon\}/g,
|
175
|
+
templateName : /\{name\}/i,
|
176
|
+
spaces : /\s+/g,
|
177
|
+
nonWord : /\W/g,
|
178
|
+
formElements : /(input|select|button|textarea)/i
|
179
|
+
};
|
180
|
+
|
172
181
|
// These methods can be applied on table.config instance
|
173
182
|
ts.instanceMethods = {};
|
174
183
|
|
@@ -461,7 +470,9 @@
|
|
461
470
|
// if headerTemplate is empty, don't reformat the header cell
|
462
471
|
if ( c.headerTemplate !== '' && !$t.find('.' + ts.css.headerIn).length ) {
|
463
472
|
// set up header template
|
464
|
-
t = c.headerTemplate
|
473
|
+
t = c.headerTemplate
|
474
|
+
.replace(ts.regex.templateContent, $t.html())
|
475
|
+
.replace(ts.regex.templateIcon, $t.find('.' + ts.css.icon).length ? '' : i);
|
465
476
|
if (c.onRenderTemplate) {
|
466
477
|
h = c.onRenderTemplate.apply( $t, [ index, t ] );
|
467
478
|
if (h && typeof h === 'string') { t = h; } // only change t if something is returned
|
@@ -874,7 +885,7 @@
|
|
874
885
|
.join( c.namespace + ' ' );
|
875
886
|
// apply easy methods that trigger bound events
|
876
887
|
$table
|
877
|
-
.unbind( events.replace(
|
888
|
+
.unbind( events.replace( ts.regex.spaces, ' ' ) )
|
878
889
|
.bind( 'sortReset' + c.namespace, function( e, callback ) {
|
879
890
|
e.stopPropagation();
|
880
891
|
// using this.config to ensure functions are getting a non-cached version of the config
|
@@ -1021,7 +1032,7 @@
|
|
1021
1032
|
c.namespace = '.tablesorter' + Math.random().toString(16).slice(2);
|
1022
1033
|
} else {
|
1023
1034
|
// make sure namespace starts with a period & doesn't have weird characters
|
1024
|
-
c.namespace = '.' + c.namespace.replace(
|
1035
|
+
c.namespace = '.' + c.namespace.replace(ts.regex.nonWord, '');
|
1025
1036
|
}
|
1026
1037
|
|
1027
1038
|
c.$table.children().children('tr').attr('role', 'row');
|
@@ -1249,7 +1260,7 @@
|
|
1249
1260
|
}
|
1250
1261
|
}
|
1251
1262
|
t = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
|
1252
|
-
.replace(
|
1263
|
+
.replace(ts.regex.spaces, ' ')
|
1253
1264
|
.split(' ')
|
1254
1265
|
.join(c.namespace + ' ');
|
1255
1266
|
// apply event handling to headers and/or additional headers (stickyheaders, scroller, etc)
|
@@ -1283,7 +1294,7 @@
|
|
1283
1294
|
}
|
1284
1295
|
downTarget = null;
|
1285
1296
|
// prevent sort being triggered on form elements
|
1286
|
-
if (
|
1297
|
+
if ( ts.regex.formElements.test(e.target.nodeName) ||
|
1287
1298
|
// nosort class name, or elements within a nosort container
|
1288
1299
|
$target.hasClass(c.cssNoSort) || $target.parents('.' + c.cssNoSort).length > 0 ||
|
1289
1300
|
// elements within a button
|
@@ -1569,13 +1580,13 @@
|
|
1569
1580
|
.join(c.namespace + ' ');
|
1570
1581
|
$t
|
1571
1582
|
.removeData('tablesorter')
|
1572
|
-
.unbind( events.replace(
|
1583
|
+
.unbind( events.replace(ts.regex.spaces, ' ') );
|
1573
1584
|
c.$headers.add($f)
|
1574
1585
|
.removeClass( [ ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone ].join(' ') )
|
1575
1586
|
.removeAttr('data-column')
|
1576
1587
|
.removeAttr('aria-label')
|
1577
1588
|
.attr('aria-disabled', 'true');
|
1578
|
-
$r.find(c.selectorSort).unbind( ('mousedown mouseup keypress '.split(' ').join(c.namespace + ' ')).replace(
|
1589
|
+
$r.find(c.selectorSort).unbind( ('mousedown mouseup keypress '.split(' ').join(c.namespace + ' ')).replace(ts.regex.spaces, ' ') );
|
1579
1590
|
ts.restoreHeaders(table);
|
1580
1591
|
$t.toggleClass(ts.css.table + ' ' + c.tableClass + ' tablesorter-' + c.theme, removeClasses === false);
|
1581
1592
|
// clear flag in case the plugin is initialized again
|
@@ -1591,11 +1602,9 @@
|
|
1591
1602
|
|
1592
1603
|
// *** sort functions ***
|
1593
1604
|
// regex used in natural sort
|
1594
|
-
ts.regex =
|
1595
|
-
|
1596
|
-
|
1597
|
-
hex: /^0x[0-9a-f]+$/i // hex
|
1598
|
-
};
|
1605
|
+
ts.regex.chunk = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi; // chunk/tokenize numbers & letters
|
1606
|
+
ts.regex.chunks = /(^\\0|\\0$)/; // replace chunks @ ends
|
1607
|
+
ts.regex.hex = /^0x[0-9a-f]+$/i; // hex
|
1599
1608
|
|
1600
1609
|
// Natural sort - https://github.com/overset/javascript-natural-sort (date sorting removed)
|
1601
1610
|
// this function will only accept strings, or you'll see 'TypeError: undefined is not a function'
|
@@ -1822,7 +1831,7 @@
|
|
1822
1831
|
if (c.debug) { time = new Date(); }
|
1823
1832
|
// look for widgets to apply from in table class
|
1824
1833
|
// stop using \b otherwise this matches 'ui-widget-content' & adds 'content' widget
|
1825
|
-
wd = new RegExp( '\\s' + c.widgetClass.replace(
|
1834
|
+
wd = new RegExp( '\\s' + c.widgetClass.replace( ts.regex.templateName, '([\\w-]+)' ) + '\\s', 'g' );
|
1826
1835
|
if ( tableClass.match( wd ) ) {
|
1827
1836
|
// extract out the widget id from the table class (widget id's can include dashes)
|
1828
1837
|
w = tableClass.match( wd );
|
@@ -2048,6 +2057,10 @@
|
|
2048
2057
|
return $.trim(val);
|
2049
2058
|
};
|
2050
2059
|
|
2060
|
+
ts.regex.comma = /,/g;
|
2061
|
+
ts.regex.digitNonUS = /[\s|\.]/g;
|
2062
|
+
ts.regex.digitNegativeTest = /^\s*\([.\d]+\)/;
|
2063
|
+
ts.regex.digitNegativeReplace = /^\s*\(([.\d]+)\)/;
|
2051
2064
|
ts.formatFloat = function(s, table) {
|
2052
2065
|
if (typeof s !== 'string' || s === '') { return s; }
|
2053
2066
|
// allow using formatFloat without a table; defaults to US number format
|
@@ -2056,24 +2069,28 @@
|
|
2056
2069
|
typeof table !== 'undefined' ? table : true;
|
2057
2070
|
if (t) {
|
2058
2071
|
// US Format - 1,234,567.89 -> 1234567.89
|
2059
|
-
s = s.replace(
|
2072
|
+
s = s.replace(ts.regex.comma, '');
|
2060
2073
|
} else {
|
2061
2074
|
// German Format = 1.234.567,89 -> 1234567.89
|
2062
2075
|
// French Format = 1 234 567,89 -> 1234567.89
|
2063
|
-
s = s.replace(
|
2076
|
+
s = s.replace(ts.regex.digitNonUS, '').replace(ts.regex.comma, '.');
|
2064
2077
|
}
|
2065
|
-
if (
|
2078
|
+
if (ts.regex.digitNegativeTest.test(s)) {
|
2066
2079
|
// make (#) into a negative number -> (10) = -10
|
2067
|
-
s = s.replace(
|
2080
|
+
s = s.replace(ts.regex.digitNegativeReplace, '-$1');
|
2068
2081
|
}
|
2069
2082
|
i = parseFloat(s);
|
2070
2083
|
// return the text instead of zero
|
2071
2084
|
return isNaN(i) ? $.trim(s) : i;
|
2072
2085
|
};
|
2073
2086
|
|
2087
|
+
ts.regex.digitTest = /^[\-+(]?\d+[)]?$/;
|
2088
|
+
ts.regex.digitReplace = /[,.'"\s]/g;
|
2074
2089
|
ts.isDigit = function(s) {
|
2075
2090
|
// replace all unwanted chars and match
|
2076
|
-
return isNaN(s) ?
|
2091
|
+
return isNaN(s) ?
|
2092
|
+
ts.regex.digitTest.test( s.toString().replace( ts.regex.digitReplace, '' ) ) :
|
2093
|
+
s !== '';
|
2077
2094
|
};
|
2078
2095
|
|
2079
2096
|
}()
|
@@ -2132,65 +2149,76 @@
|
|
2132
2149
|
type: 'text'
|
2133
2150
|
});
|
2134
2151
|
|
2152
|
+
ts.regex.nondigit = /[^\w,. \-()]/g;
|
2135
2153
|
ts.addParser({
|
2136
2154
|
id: 'digit',
|
2137
2155
|
is: function(s) {
|
2138
2156
|
return ts.isDigit(s);
|
2139
2157
|
},
|
2140
2158
|
format: function(s, table) {
|
2141
|
-
var n = ts.formatFloat((s || '').replace(
|
2159
|
+
var n = ts.formatFloat((s || '').replace(ts.regex.nondigit, ''), table);
|
2142
2160
|
return s && typeof n === 'number' ? n :
|
2143
2161
|
s ? $.trim( s && table.config.ignoreCase ? s.toLocaleLowerCase() : s ) : s;
|
2144
2162
|
},
|
2145
2163
|
type: 'numeric'
|
2146
2164
|
});
|
2147
2165
|
|
2166
|
+
ts.regex.currencyReplace = /[+\-,. ]/g;
|
2167
|
+
ts.regex.currencyTest = /^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/;
|
2148
2168
|
ts.addParser({
|
2149
2169
|
id: 'currency',
|
2150
2170
|
is: function(s) {
|
2151
|
-
s = (s || '').replace(
|
2171
|
+
s = (s || '').replace(ts.regex.currencyReplace, '');
|
2152
2172
|
// test for £$€¤¥¢
|
2153
|
-
return
|
2173
|
+
return ts.regex.currencyTest.test(s);
|
2154
2174
|
},
|
2155
2175
|
format: function(s, table) {
|
2156
|
-
var n = ts.formatFloat((s || '').replace(
|
2176
|
+
var n = ts.formatFloat((s || '').replace(ts.regex.nondigit, ''), table);
|
2157
2177
|
return s && typeof n === 'number' ? n :
|
2158
2178
|
s ? $.trim( s && table.config.ignoreCase ? s.toLocaleLowerCase() : s ) : s;
|
2159
2179
|
},
|
2160
2180
|
type: 'numeric'
|
2161
2181
|
});
|
2162
2182
|
|
2183
|
+
// too many protocols to add them all https://en.wikipedia.org/wiki/URI_scheme
|
2184
|
+
// now, this regex can be updated before initialization
|
2185
|
+
ts.regex.urlProtocolTest = /^(https?|ftp|file):\/\//;
|
2186
|
+
ts.regex.urlProtocolReplace = /(https?|ftp|file):\/\//;
|
2163
2187
|
ts.addParser({
|
2164
2188
|
id: 'url',
|
2165
2189
|
is: function(s) {
|
2166
|
-
return
|
2190
|
+
return ts.regex.urlProtocolTest.test(s);
|
2167
2191
|
},
|
2168
2192
|
format: function(s) {
|
2169
|
-
return s ? $.trim(s.replace(
|
2193
|
+
return s ? $.trim(s.replace(ts.regex.urlProtocolReplace, '')) : s;
|
2170
2194
|
},
|
2171
2195
|
parsed : true, // filter widget flag
|
2172
2196
|
type: 'text'
|
2173
2197
|
});
|
2174
2198
|
|
2199
|
+
ts.regex.dash = /-/g;
|
2200
|
+
ts.regex.isoDate = /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/;
|
2175
2201
|
ts.addParser({
|
2176
2202
|
id: 'isoDate',
|
2177
2203
|
is: function(s) {
|
2178
|
-
return
|
2204
|
+
return ts.regex.isoDate.test(s);
|
2179
2205
|
},
|
2180
2206
|
format: function(s, table) {
|
2181
|
-
var date = s ? new Date( s.replace(
|
2207
|
+
var date = s ? new Date( s.replace(ts.regex.dash, '/') ) : s;
|
2182
2208
|
return date instanceof Date && isFinite(date) ? date.getTime() : s;
|
2183
2209
|
},
|
2184
2210
|
type: 'numeric'
|
2185
2211
|
});
|
2186
2212
|
|
2213
|
+
ts.regex.percent = /%/g;
|
2214
|
+
ts.regex.percentTest = /(\d\s*?%|%\s*?\d)/;
|
2187
2215
|
ts.addParser({
|
2188
2216
|
id: 'percent',
|
2189
2217
|
is: function(s) {
|
2190
|
-
return
|
2218
|
+
return ts.regex.percentTest.test(s) && s.length < 15;
|
2191
2219
|
},
|
2192
2220
|
format: function(s, table) {
|
2193
|
-
return s ? ts.formatFloat(s.replace(
|
2221
|
+
return s ? ts.formatFloat(s.replace(ts.regex.percent, ''), table) : s;
|
2194
2222
|
},
|
2195
2223
|
type: 'numeric'
|
2196
2224
|
});
|
@@ -2208,27 +2236,35 @@
|
|
2208
2236
|
type: 'text'
|
2209
2237
|
});
|
2210
2238
|
|
2239
|
+
ts.regex.dateReplace = /(\S)([AP]M)$/i; // used by usLongDate & time parser
|
2240
|
+
ts.regex.usLongDateTest1 = /^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i;
|
2241
|
+
ts.regex.usLongDateTest2 = /^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i;
|
2211
2242
|
ts.addParser({
|
2212
2243
|
id: 'usLongDate',
|
2213
2244
|
is: function(s) {
|
2214
2245
|
// two digit years are not allowed cross-browser
|
2215
2246
|
// Jan 01, 2013 12:34:56 PM or 01 Jan 2013
|
2216
|
-
return (
|
2217
|
-
(/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i).test(s);
|
2247
|
+
return ts.regex.usLongDateTest1.test(s) || ts.regex.usLongDateTest2.test(s);
|
2218
2248
|
},
|
2219
2249
|
format: function(s, table) {
|
2220
|
-
var date = s ? new Date( s.replace(
|
2250
|
+
var date = s ? new Date( s.replace(ts.regex.dateReplace, '$1 $2') ) : s;
|
2221
2251
|
return date instanceof Date && isFinite(date) ? date.getTime() : s;
|
2222
2252
|
},
|
2223
2253
|
type: 'numeric'
|
2224
2254
|
});
|
2225
2255
|
|
2256
|
+
// testing for ##-##-#### or ####-##-##, so it's not perfect; time can be included
|
2257
|
+
ts.regex.shortDateTest = /(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/;
|
2258
|
+
// escaped "-" because JSHint in Firefox was showing it as an error
|
2259
|
+
ts.regex.shortDateReplace = /[\-.,]/g;
|
2260
|
+
// XXY covers MDY & DMY formats
|
2261
|
+
ts.regex.shortDateXXY = /(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/;
|
2262
|
+
ts.regex.shortDateYMD = /(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/;
|
2226
2263
|
ts.addParser({
|
2227
2264
|
id: 'shortDate', // 'mmddyyyy', 'ddmmyyyy' or 'yyyymmdd'
|
2228
2265
|
is: function(s) {
|
2229
|
-
s = (s || '').replace(
|
2230
|
-
|
2231
|
-
return (/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/).test(s);
|
2266
|
+
s = (s || '').replace(ts.regex.spaces, ' ').replace(ts.regex.shortDateReplace, '/');
|
2267
|
+
return ts.regex.shortDateTest.test(s);
|
2232
2268
|
},
|
2233
2269
|
format: function(s, table, cell, cellIndex) {
|
2234
2270
|
if (s) {
|
@@ -2238,14 +2274,13 @@
|
|
2238
2274
|
format = ci.length && ci[0].dateFormat ||
|
2239
2275
|
ts.getData( ci, ts.getColumnData( table, c.headers, cellIndex ), 'dateFormat') ||
|
2240
2276
|
c.dateFormat;
|
2241
|
-
|
2242
|
-
d = s.replace(/\s+/g, ' ').replace(/[\-.,]/g, '/');
|
2277
|
+
d = s.replace(ts.regex.spaces, ' ').replace(ts.regex.shortDateReplace, '/');
|
2243
2278
|
if (format === 'mmddyyyy') {
|
2244
|
-
d = d.replace(
|
2279
|
+
d = d.replace(ts.regex.shortDateXXY, '$3/$1/$2');
|
2245
2280
|
} else if (format === 'ddmmyyyy') {
|
2246
|
-
d = d.replace(
|
2281
|
+
d = d.replace(ts.regex.shortDateXXY, '$3/$2/$1');
|
2247
2282
|
} else if (format === 'yyyymmdd') {
|
2248
|
-
d = d.replace(
|
2283
|
+
d = d.replace(ts.regex.shortDateYMD, '$1/$2/$3');
|
2249
2284
|
}
|
2250
2285
|
date = new Date(d);
|
2251
2286
|
return date instanceof Date && isFinite(date) ? date.getTime() : s;
|
@@ -2255,13 +2290,14 @@
|
|
2255
2290
|
type: 'numeric'
|
2256
2291
|
});
|
2257
2292
|
|
2293
|
+
ts.regex.timeTest = /^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i;
|
2258
2294
|
ts.addParser({
|
2259
2295
|
id: 'time',
|
2260
2296
|
is: function(s) {
|
2261
|
-
return
|
2297
|
+
return ts.regex.timeTest.test(s);
|
2262
2298
|
},
|
2263
2299
|
format: function(s, table) {
|
2264
|
-
var date = s ? new Date( '2000/01/01 ' + s.replace(
|
2300
|
+
var date = s ? new Date( '2000/01/01 ' + s.replace(ts.regex.dateReplace, '$1 $2') ) : s;
|
2265
2301
|
return date instanceof Date && isFinite(date) ? date.getTime() : s;
|
2266
2302
|
},
|
2267
2303
|
type: 'numeric'
|
@@ -2678,14 +2714,15 @@
|
|
2678
2714
|
|
2679
2715
|
})(jQuery);
|
2680
2716
|
|
2681
|
-
/*! Widget: filter - updated 8/
|
2717
|
+
/*! Widget: filter - updated 8/23/2015 (v2.23.2) *//*
|
2682
2718
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
2683
2719
|
* by Rob Garrison
|
2684
2720
|
*/
|
2685
2721
|
;( function ( $ ) {
|
2686
2722
|
'use strict';
|
2687
|
-
var
|
2688
|
-
|
2723
|
+
var tsf,
|
2724
|
+
ts = $.tablesorter || {},
|
2725
|
+
tscss = ts.css;
|
2689
2726
|
|
2690
2727
|
$.extend( tscss, {
|
2691
2728
|
filterRow : 'tablesorter-filter-row',
|
@@ -2729,7 +2766,7 @@
|
|
2729
2766
|
},
|
2730
2767
|
format: function( table, c, wo ) {
|
2731
2768
|
if ( !c.$table.hasClass( 'hasFilters' ) ) {
|
2732
|
-
|
2769
|
+
tsf.init( table, c, wo );
|
2733
2770
|
}
|
2734
2771
|
},
|
2735
2772
|
remove: function( table, c, wo, refreshing ) {
|
@@ -2741,7 +2778,7 @@
|
|
2741
2778
|
$table
|
2742
2779
|
.removeClass( 'hasFilters' )
|
2743
2780
|
// add .tsfilter namespace to all BUT search
|
2744
|
-
.unbind( events.replace(
|
2781
|
+
.unbind( events.replace( ts.regex.spaces, ' ' ) )
|
2745
2782
|
// remove the filter row even if refreshing, because the column might have been moved
|
2746
2783
|
.find( '.' + tscss.filterRow ).remove();
|
2747
2784
|
if ( refreshing ) { return; }
|
@@ -2756,7 +2793,7 @@
|
|
2756
2793
|
}
|
2757
2794
|
});
|
2758
2795
|
|
2759
|
-
ts.filter = {
|
2796
|
+
tsf = ts.filter = {
|
2760
2797
|
|
2761
2798
|
// regex used in filter 'check' functions - not for general use and not documented
|
2762
2799
|
regex: {
|
@@ -2765,9 +2802,13 @@
|
|
2765
2802
|
filtered : /filtered/, // filtered (hidden) row class name; updated in the script
|
2766
2803
|
type : /undefined|number/, // check type
|
2767
2804
|
exact : /(^[\"\'=]+)|([\"\'=]+$)/g, // exact match (allow '==')
|
2768
|
-
nondigit : /[^\w,. \-()]/g, // replace non-digits (from digit & currency parser)
|
2769
2805
|
operators : /[<>=]/g, // replace operators
|
2770
|
-
query : '(q|query)' // replace filter queries
|
2806
|
+
query : '(q|query)', // replace filter queries
|
2807
|
+
wild01 : /\?/g, // wild card match 0 or 1
|
2808
|
+
wild0More : /\*/g, // wild care match 0 or more
|
2809
|
+
quote : /\"/g,
|
2810
|
+
isNeg1 : /(>=?\s*-\d)/,
|
2811
|
+
isNeg2 : /(<=?\s*\d)/
|
2771
2812
|
},
|
2772
2813
|
// function( c, data ) { }
|
2773
2814
|
// c = table.config
|
@@ -2784,27 +2825,27 @@
|
|
2784
2825
|
// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
|
2785
2826
|
types: {
|
2786
2827
|
or : function( c, data, vars ) {
|
2787
|
-
if (
|
2828
|
+
if ( tsf.regex.orTest.test( data.iFilter ) || tsf.regex.orSplit.test( data.filter ) ) {
|
2788
2829
|
var indx, filterMatched, query, regex,
|
2789
2830
|
// duplicate data but split filter
|
2790
2831
|
data2 = $.extend( {}, data ),
|
2791
2832
|
index = data.index,
|
2792
2833
|
parsed = data.parsed[ index ],
|
2793
|
-
filter = data.filter.split(
|
2794
|
-
iFilter = data.iFilter.split(
|
2834
|
+
filter = data.filter.split( tsf.regex.orSplit ),
|
2835
|
+
iFilter = data.iFilter.split( tsf.regex.orSplit ),
|
2795
2836
|
len = filter.length;
|
2796
2837
|
for ( indx = 0; indx < len; indx++ ) {
|
2797
2838
|
data2.nestedFilters = true;
|
2798
|
-
data2.filter = '' + (
|
2799
|
-
data2.iFilter = '' + (
|
2800
|
-
query = '(' + (
|
2839
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], index, parsed ) || '' );
|
2840
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
|
2841
|
+
query = '(' + ( tsf.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')';
|
2801
2842
|
try {
|
2802
2843
|
// use try/catch, because query may not be a valid regex if "|" is contained within a partial regex search,
|
2803
2844
|
// e.g "/(Alex|Aar" -> Uncaught SyntaxError: Invalid regular expression: /(/(Alex)/: Unterminated group
|
2804
2845
|
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
2805
2846
|
// filterMatched = data2.filter === '' && indx > 0 ? true
|
2806
2847
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
2807
|
-
filterMatched = regex.test( data2.exact ) ||
|
2848
|
+
filterMatched = regex.test( data2.exact ) || tsf.processTypes( c, data2, vars );
|
2808
2849
|
if ( filterMatched ) {
|
2809
2850
|
return filterMatched;
|
2810
2851
|
}
|
@@ -2819,27 +2860,27 @@
|
|
2819
2860
|
},
|
2820
2861
|
// Look for an AND or && operator ( logical and )
|
2821
2862
|
and : function( c, data, vars ) {
|
2822
|
-
if (
|
2863
|
+
if ( tsf.regex.andTest.test( data.filter ) ) {
|
2823
2864
|
var indx, filterMatched, result, query, regex,
|
2824
2865
|
// duplicate data but split filter
|
2825
2866
|
data2 = $.extend( {}, data ),
|
2826
2867
|
index = data.index,
|
2827
2868
|
parsed = data.parsed[ index ],
|
2828
|
-
filter = data.filter.split(
|
2829
|
-
iFilter = data.iFilter.split(
|
2869
|
+
filter = data.filter.split( tsf.regex.andSplit ),
|
2870
|
+
iFilter = data.iFilter.split( tsf.regex.andSplit ),
|
2830
2871
|
len = filter.length;
|
2831
2872
|
for ( indx = 0; indx < len; indx++ ) {
|
2832
2873
|
data2.nestedFilters = true;
|
2833
|
-
data2.filter = '' + (
|
2834
|
-
data2.iFilter = '' + (
|
2835
|
-
query = ( '(' + (
|
2874
|
+
data2.filter = '' + ( tsf.parseFilter( c, filter[ indx ], index, parsed ) || '' );
|
2875
|
+
data2.iFilter = '' + ( tsf.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
|
2876
|
+
query = ( '(' + ( tsf.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')' )
|
2836
2877
|
// replace wild cards since /(a*)/i will match anything
|
2837
|
-
.replace(
|
2878
|
+
.replace( tsf.regex.wild01, '\\S{1}' ).replace( tsf.regex.wild0More, '\\S*' );
|
2838
2879
|
try {
|
2839
2880
|
// use try/catch just in case RegExp is invalid
|
2840
2881
|
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
2841
2882
|
// look for an exact match with the 'and' unless the 'filter-match' class is found
|
2842
|
-
result = ( regex.test( data2.exact ) ||
|
2883
|
+
result = ( regex.test( data2.exact ) || tsf.processTypes( c, data2, vars ) );
|
2843
2884
|
if ( indx === 0 ) {
|
2844
2885
|
filterMatched = result;
|
2845
2886
|
} else {
|
@@ -2856,10 +2897,10 @@
|
|
2856
2897
|
},
|
2857
2898
|
// Look for regex
|
2858
2899
|
regex: function( c, data ) {
|
2859
|
-
if (
|
2900
|
+
if ( tsf.regex.regex.test( data.filter ) ) {
|
2860
2901
|
var matches,
|
2861
2902
|
// cache regex per column for optimal speed
|
2862
|
-
regex = data.filter_regexCache[ data.index ] ||
|
2903
|
+
regex = data.filter_regexCache[ data.index ] || tsf.regex.regex.exec( data.filter ),
|
2863
2904
|
isRegex = regex instanceof RegExp;
|
2864
2905
|
try {
|
2865
2906
|
if ( !isRegex ) {
|
@@ -2878,18 +2919,18 @@
|
|
2878
2919
|
// Look for operators >, >=, < or <=
|
2879
2920
|
operators: function( c, data ) {
|
2880
2921
|
// ignore empty strings... because '' < 10 is true
|
2881
|
-
if (
|
2922
|
+
if ( tsf.regex.operTest.test( data.iFilter ) && data.iExact !== '' ) {
|
2882
2923
|
var cachedValue, result, txt,
|
2883
2924
|
table = c.table,
|
2884
2925
|
index = data.index,
|
2885
2926
|
parsed = data.parsed[index],
|
2886
|
-
query = ts.formatFloat( data.iFilter.replace(
|
2927
|
+
query = ts.formatFloat( data.iFilter.replace( tsf.regex.operators, '' ), table ),
|
2887
2928
|
parser = c.parsers[index],
|
2888
2929
|
savedSearch = query;
|
2889
2930
|
// parse filter value in case we're comparing numbers ( dates )
|
2890
2931
|
if ( parsed || parser.type === 'numeric' ) {
|
2891
|
-
txt = $.trim( '' + data.iFilter.replace(
|
2892
|
-
result =
|
2932
|
+
txt = $.trim( '' + data.iFilter.replace( tsf.regex.operators, '' ) );
|
2933
|
+
result = tsf.parseFilter( c, txt, index, true );
|
2893
2934
|
query = ( typeof result === 'number' && result !== '' && !isNaN( result ) ) ? result : query;
|
2894
2935
|
}
|
2895
2936
|
// iExact may be numeric - see issue #149;
|
@@ -2898,13 +2939,13 @@
|
|
2898
2939
|
typeof data.cache !== 'undefined' ) {
|
2899
2940
|
cachedValue = data.cache;
|
2900
2941
|
} else {
|
2901
|
-
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.
|
2942
|
+
txt = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
|
2902
2943
|
cachedValue = ts.formatFloat( txt, table );
|
2903
2944
|
}
|
2904
|
-
if (
|
2905
|
-
result =
|
2906
|
-
} else if (
|
2907
|
-
result =
|
2945
|
+
if ( tsf.regex.gtTest.test( data.iFilter ) ) {
|
2946
|
+
result = tsf.regex.gteTest.test( data.iFilter ) ? cachedValue >= query : cachedValue > query;
|
2947
|
+
} else if ( tsf.regex.ltTest.test( data.iFilter ) ) {
|
2948
|
+
result = tsf.regex.lteTest.test( data.iFilter ) ? cachedValue <= query : cachedValue < query;
|
2908
2949
|
}
|
2909
2950
|
// keep showing all rows if nothing follows the operator
|
2910
2951
|
if ( !result && savedSearch === '' ) {
|
@@ -2916,13 +2957,13 @@
|
|
2916
2957
|
},
|
2917
2958
|
// Look for a not match
|
2918
2959
|
notMatch: function( c, data ) {
|
2919
|
-
if (
|
2960
|
+
if ( tsf.regex.notTest.test( data.iFilter ) ) {
|
2920
2961
|
var indx,
|
2921
2962
|
txt = data.iFilter.replace( '!', '' ),
|
2922
|
-
filter =
|
2923
|
-
if (
|
2963
|
+
filter = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
2964
|
+
if ( tsf.regex.exact.test( filter ) ) {
|
2924
2965
|
// look for exact not matches - see #628
|
2925
|
-
filter = filter.replace(
|
2966
|
+
filter = filter.replace( tsf.regex.exact, '' );
|
2926
2967
|
return filter === '' ? true : $.trim( filter ) !== data.iExact;
|
2927
2968
|
} else {
|
2928
2969
|
indx = data.iExact.search( $.trim( filter ) );
|
@@ -2934,27 +2975,27 @@
|
|
2934
2975
|
// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
|
2935
2976
|
exact: function( c, data ) {
|
2936
2977
|
/*jshint eqeqeq:false */
|
2937
|
-
if (
|
2938
|
-
var txt = data.iFilter.replace(
|
2939
|
-
filter =
|
2978
|
+
if ( tsf.regex.exact.test( data.iFilter ) ) {
|
2979
|
+
var txt = data.iFilter.replace( tsf.regex.exact, '' ),
|
2980
|
+
filter = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
2940
2981
|
return data.anyMatch ? $.inArray( filter, data.rowArray ) >= 0 : filter == data.iExact;
|
2941
2982
|
}
|
2942
2983
|
return null;
|
2943
2984
|
},
|
2944
2985
|
// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
|
2945
2986
|
range : function( c, data ) {
|
2946
|
-
if (
|
2987
|
+
if ( tsf.regex.toTest.test( data.iFilter ) ) {
|
2947
2988
|
var result, tmp, range1, range2,
|
2948
2989
|
table = c.table,
|
2949
2990
|
index = data.index,
|
2950
2991
|
parsed = data.parsed[index],
|
2951
2992
|
// make sure the dash is for a range and not indicating a negative number
|
2952
|
-
query = data.iFilter.split(
|
2993
|
+
query = data.iFilter.split( tsf.regex.toSplit );
|
2953
2994
|
|
2954
|
-
tmp = query[0].replace( ts.
|
2955
|
-
range1 = ts.formatFloat(
|
2956
|
-
tmp = query[1].replace( ts.
|
2957
|
-
range2 = ts.formatFloat(
|
2995
|
+
tmp = query[0].replace( ts.regex.nondigit, '' ) || '';
|
2996
|
+
range1 = ts.formatFloat( tsf.parseFilter( c, tmp, index, parsed ), table );
|
2997
|
+
tmp = query[1].replace( ts.regex.nondigit, '' ) || '';
|
2998
|
+
range2 = ts.formatFloat( tsf.parseFilter( c, tmp, index, parsed ), table );
|
2958
2999
|
// parse filter value in case we're comparing numbers ( dates )
|
2959
3000
|
if ( parsed || c.parsers[index].type === 'numeric' ) {
|
2960
3001
|
result = c.parsers[ index ].format( '' + query[0], table, c.$headers.eq( index ), index );
|
@@ -2965,7 +3006,7 @@
|
|
2965
3006
|
if ( ( parsed || c.parsers[ index ].type === 'numeric' ) && !isNaN( range1 ) && !isNaN( range2 ) ) {
|
2966
3007
|
result = data.cache;
|
2967
3008
|
} else {
|
2968
|
-
tmp = isNaN( data.iExact ) ? data.iExact.replace( ts.
|
3009
|
+
tmp = isNaN( data.iExact ) ? data.iExact.replace( ts.regex.nondigit, '' ) : data.iExact;
|
2969
3010
|
result = ts.formatFloat( tmp, table );
|
2970
3011
|
}
|
2971
3012
|
if ( range1 > range2 ) {
|
@@ -2977,18 +3018,18 @@
|
|
2977
3018
|
},
|
2978
3019
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
2979
3020
|
wild : function( c, data ) {
|
2980
|
-
if (
|
3021
|
+
if ( tsf.regex.wildOrTest.test( data.iFilter ) ) {
|
2981
3022
|
var index = data.index,
|
2982
3023
|
parsed = data.parsed[ index ],
|
2983
|
-
query = '' + (
|
3024
|
+
query = '' + ( tsf.parseFilter( c, data.iFilter, index, parsed ) || '' );
|
2984
3025
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
2985
|
-
if (
|
3026
|
+
if ( !tsf.regex.wildTest.test( query ) && data.nestedFilters ) {
|
2986
3027
|
query = data.isMatch ? query : '^(' + query + ')$';
|
2987
3028
|
}
|
2988
3029
|
// parsing the filter may not work properly when using wildcards =/
|
2989
3030
|
try {
|
2990
3031
|
return new RegExp(
|
2991
|
-
query.replace(
|
3032
|
+
query.replace( tsf.regex.wild01, '\\S{1}' ).replace( tsf.regex.wild0More, '\\S*' ),
|
2992
3033
|
c.widgetOptions.filter_ignoreCase ? 'i' : ''
|
2993
3034
|
)
|
2994
3035
|
.test( data.exact );
|
@@ -3000,12 +3041,12 @@
|
|
3000
3041
|
},
|
3001
3042
|
// fuzzy text search; modified from https://github.com/mattyork/fuzzy ( MIT license )
|
3002
3043
|
fuzzy: function( c, data ) {
|
3003
|
-
if (
|
3044
|
+
if ( tsf.regex.fuzzyTest.test( data.iFilter ) ) {
|
3004
3045
|
var indx,
|
3005
3046
|
patternIndx = 0,
|
3006
3047
|
len = data.iExact.length,
|
3007
3048
|
txt = data.iFilter.slice( 1 ),
|
3008
|
-
pattern =
|
3049
|
+
pattern = tsf.parseFilter( c, txt, data.index, data.parsed[data.index] ) || '';
|
3009
3050
|
for ( indx = 0; indx < len; indx++ ) {
|
3010
3051
|
if ( data.iExact[ indx ] === pattern[ patternIndx ] ) {
|
3011
3052
|
patternIndx += 1;
|
@@ -3028,7 +3069,7 @@
|
|
3028
3069
|
}, ts.language );
|
3029
3070
|
|
3030
3071
|
var options, string, txt, $header, column, filters, val, fxn, noSelect,
|
3031
|
-
regex =
|
3072
|
+
regex = tsf.regex;
|
3032
3073
|
c.$table.addClass( 'hasFilters' );
|
3033
3074
|
|
3034
3075
|
// define timers so using clearTimeout won't cause an undefined error
|
@@ -3039,7 +3080,7 @@
|
|
3039
3080
|
wo.filter_anyColumnSelector = '[data-column="all"],[data-column="any"]';
|
3040
3081
|
wo.filter_multipleColumnSelector = '[data-column*="-"],[data-column*=","]';
|
3041
3082
|
|
3042
|
-
val = '\\{' +
|
3083
|
+
val = '\\{' + tsf.regex.query + '\\}';
|
3043
3084
|
$.extend( regex, {
|
3044
3085
|
child : new RegExp( c.cssChildRow ),
|
3045
3086
|
filtered : new RegExp( wo.filter_filteredRow ),
|
@@ -3048,9 +3089,20 @@
|
|
3048
3089
|
toSplit : new RegExp( '(?:\\s+(?:-|' + ts.language.to + ')\\s+)', 'gi' ),
|
3049
3090
|
andTest : new RegExp( '\\s+(' + ts.language.and + '|&&)\\s+', 'i' ),
|
3050
3091
|
andSplit : new RegExp( '(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi' ),
|
3092
|
+
orTest : /\|/,
|
3051
3093
|
orSplit : new RegExp( '(?:\\s+(?:' + ts.language.or + ')\\s+|\\|)', 'gi' ),
|
3052
3094
|
iQuery : new RegExp( val, 'i' ),
|
3053
|
-
igQuery : new RegExp( val, 'ig' )
|
3095
|
+
igQuery : new RegExp( val, 'ig' ),
|
3096
|
+
operTest : /^[<>]=?/,
|
3097
|
+
gtTest : />/,
|
3098
|
+
gteTest : />=/,
|
3099
|
+
ltTest : /</,
|
3100
|
+
lteTest : /<=/,
|
3101
|
+
notTest : /^\!/,
|
3102
|
+
wildOrTest : /[\?\*\|]/,
|
3103
|
+
wildTest : /\?\*/,
|
3104
|
+
fuzzyTest : /^~/,
|
3105
|
+
exactTest : /[=\"\|!]/
|
3054
3106
|
});
|
3055
3107
|
|
3056
3108
|
// don't build filter row if columnFilters is false or all columns are set to 'filter-false'
|
@@ -3058,7 +3110,7 @@
|
|
3058
3110
|
val = c.$headers.filter( '.filter-false, .parser-false' ).length;
|
3059
3111
|
if ( wo.filter_columnFilters !== false && val !== c.$headers.length ) {
|
3060
3112
|
// build filter row
|
3061
|
-
|
3113
|
+
tsf.buildRow( table, c, wo );
|
3062
3114
|
}
|
3063
3115
|
|
3064
3116
|
txt = 'addRows updateCell update updateRows updateComplete appendCache filterReset filterEnd search '
|
@@ -3071,13 +3123,13 @@
|
|
3071
3123
|
c.$table.find( '.' + tscss.filterRow ).toggleClass( wo.filter_filteredRow, val ); // fixes #450
|
3072
3124
|
if ( !/(search|filter)/.test( event.type ) ) {
|
3073
3125
|
event.stopPropagation();
|
3074
|
-
|
3126
|
+
tsf.buildDefault( table, true );
|
3075
3127
|
}
|
3076
3128
|
if ( event.type === 'filterReset' ) {
|
3077
3129
|
c.$table.find( '.' + tscss.filter ).add( wo.filter_$externalFilters ).val( '' );
|
3078
|
-
|
3130
|
+
tsf.searching( table, [] );
|
3079
3131
|
} else if ( event.type === 'filterEnd' ) {
|
3080
|
-
|
3132
|
+
tsf.buildDefault( table, true );
|
3081
3133
|
} else {
|
3082
3134
|
// send false argument to force a new search; otherwise if the filter hasn't changed,
|
3083
3135
|
// it will return
|
@@ -3091,7 +3143,7 @@
|
|
3091
3143
|
// pass true ( skipFirst ) to prevent the tablesorter.setFilters function from skipping the first
|
3092
3144
|
// input ensures all inputs are updated when a search is triggered on the table
|
3093
3145
|
// $( 'table' ).trigger( 'search', [...] );
|
3094
|
-
|
3146
|
+
tsf.searching( table, filter, true );
|
3095
3147
|
}
|
3096
3148
|
return false;
|
3097
3149
|
});
|
@@ -3124,7 +3176,7 @@
|
|
3124
3176
|
noSelect = !( $header.hasClass( 'filter-false' ) || $header.hasClass( 'parser-false' ) );
|
3125
3177
|
options = '';
|
3126
3178
|
if ( fxn === true && noSelect ) {
|
3127
|
-
|
3179
|
+
tsf.buildSelect( table, column );
|
3128
3180
|
} else if ( typeof fxn === 'object' && noSelect ) {
|
3129
3181
|
// add custom drop down list
|
3130
3182
|
for ( string in fxn ) {
|
@@ -3157,7 +3209,7 @@
|
|
3157
3209
|
fxn = $.isFunction( txt ) ? true : ts.getColumnData( table, txt, column );
|
3158
3210
|
if ( fxn ) {
|
3159
3211
|
// updating so the extra options are appended
|
3160
|
-
|
3212
|
+
tsf.buildSelect( c.table, column, '', true, $header.hasClass( wo.filter_onlyAvail ) );
|
3161
3213
|
}
|
3162
3214
|
}
|
3163
3215
|
}
|
@@ -3165,22 +3217,22 @@
|
|
3165
3217
|
}
|
3166
3218
|
// not really updating, but if the column has both the 'filter-select' class &
|
3167
3219
|
// filter_functions set to true, it would append the same options twice.
|
3168
|
-
|
3220
|
+
tsf.buildDefault( table, true );
|
3169
3221
|
|
3170
|
-
|
3222
|
+
tsf.bindSearch( table, c.$table.find( '.' + tscss.filter ), true );
|
3171
3223
|
if ( wo.filter_external ) {
|
3172
|
-
|
3224
|
+
tsf.bindSearch( table, wo.filter_external );
|
3173
3225
|
}
|
3174
3226
|
|
3175
3227
|
if ( wo.filter_hideFilters ) {
|
3176
|
-
|
3228
|
+
tsf.hideFilters( table, c );
|
3177
3229
|
}
|
3178
3230
|
|
3179
3231
|
// show processing icon
|
3180
3232
|
if ( c.showProcessing ) {
|
3181
3233
|
txt = 'filterStart filterEnd '.split( ' ' ).join( c.namespace + 'filter ' );
|
3182
3234
|
c.$table
|
3183
|
-
.unbind( txt.replace(
|
3235
|
+
.unbind( txt.replace( ts.regex.spaces, ' ' ) )
|
3184
3236
|
.bind( txt, function( event, columns ) {
|
3185
3237
|
// only add processing to certain columns to all columns
|
3186
3238
|
$header = ( columns ) ?
|
@@ -3200,11 +3252,11 @@
|
|
3200
3252
|
// add default values
|
3201
3253
|
txt = 'tablesorter-initialized pagerBeforeInitialized '.split( ' ' ).join( c.namespace + 'filter ' );
|
3202
3254
|
c.$table
|
3203
|
-
.unbind( txt.replace(
|
3255
|
+
.unbind( txt.replace( ts.regex.spaces, ' ' ) )
|
3204
3256
|
.bind( txt, function() {
|
3205
3257
|
// redefine 'wo' as it does not update properly inside this callback
|
3206
3258
|
var wo = this.config.widgetOptions;
|
3207
|
-
filters =
|
3259
|
+
filters = tsf.setDefaults( table, c, wo ) || [];
|
3208
3260
|
if ( filters.length ) {
|
3209
3261
|
// prevent delayInit from triggering a cache build if filters are empty
|
3210
3262
|
if ( !( c.delayInit && filters.join( '' ) === '' ) ) {
|
@@ -3215,7 +3267,7 @@
|
|
3215
3267
|
// trigger init after setTimeout to prevent multiple filterStart/End/Init triggers
|
3216
3268
|
setTimeout( function() {
|
3217
3269
|
if ( !wo.filter_initialized ) {
|
3218
|
-
|
3270
|
+
tsf.filterInitComplete( c );
|
3219
3271
|
}
|
3220
3272
|
}, 100 );
|
3221
3273
|
});
|
@@ -3223,7 +3275,7 @@
|
|
3223
3275
|
if ( c.pager && c.pager.initialized && !wo.filter_initialized ) {
|
3224
3276
|
c.$table.trigger( 'filterFomatterUpdate' );
|
3225
3277
|
setTimeout( function() {
|
3226
|
-
|
3278
|
+
tsf.filterInitComplete( c );
|
3227
3279
|
}, 100 );
|
3228
3280
|
}
|
3229
3281
|
},
|
@@ -3244,7 +3296,7 @@
|
|
3244
3296
|
completed = function() {
|
3245
3297
|
wo.filter_initialized = true;
|
3246
3298
|
c.$table.trigger( 'filterInit', c );
|
3247
|
-
|
3299
|
+
tsf.findRows( c.table, c.$table.data( 'lastSearch' ) || [] );
|
3248
3300
|
};
|
3249
3301
|
if ( $.isEmptyObject( wo.filter_formatter ) ) {
|
3250
3302
|
completed();
|
@@ -3396,7 +3448,7 @@
|
|
3396
3448
|
// use data attribute instead of jQuery data since the head is cloned without including
|
3397
3449
|
// the data/binding
|
3398
3450
|
.attr( 'data-lastSearchTime', new Date().getTime() )
|
3399
|
-
.unbind( tmp.replace(
|
3451
|
+
.unbind( tmp.replace( ts.regex.spaces, ' ' ) )
|
3400
3452
|
// include change for select - fixes #473
|
3401
3453
|
.bind( 'keyup' + namespace, function( event ) {
|
3402
3454
|
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
|
@@ -3416,17 +3468,18 @@
|
|
3416
3468
|
return;
|
3417
3469
|
}
|
3418
3470
|
// change event = no delay; last true flag tells getFilters to skip newest timed input
|
3419
|
-
|
3471
|
+
tsf.searching( table, true, true );
|
3420
3472
|
})
|
3421
3473
|
.bind( 'search change keypress '.split( ' ' ).join( namespace + ' ' ), function( event ) {
|
3422
|
-
|
3474
|
+
// don't get cached data, in case data-column changes dynamically
|
3475
|
+
var column = parseInt( $( this ).attr( 'data-column' ), 10 );
|
3423
3476
|
// don't allow 'change' event to process if the input value is the same - fixes #685
|
3424
3477
|
if ( event.which === 13 || event.type === 'search' ||
|
3425
3478
|
event.type === 'change' && this.value !== c.lastSearch[column] ) {
|
3426
3479
|
event.preventDefault();
|
3427
3480
|
// init search with no delay
|
3428
3481
|
$( this ).attr( 'data-lastSearchTime', new Date().getTime() );
|
3429
|
-
|
3482
|
+
tsf.searching( table, false, true );
|
3430
3483
|
}
|
3431
3484
|
});
|
3432
3485
|
},
|
@@ -3436,11 +3489,11 @@
|
|
3436
3489
|
if ( typeof filter === 'undefined' || filter === true ) {
|
3437
3490
|
// delay filtering
|
3438
3491
|
wo.searchTimer = setTimeout( function() {
|
3439
|
-
|
3492
|
+
tsf.checkFilters( table, filter, skipFirst );
|
3440
3493
|
}, wo.filter_liveSearch ? wo.filter_searchDelay : 10 );
|
3441
3494
|
} else {
|
3442
3495
|
// skip delay
|
3443
|
-
|
3496
|
+
tsf.checkFilters( table, filter, skipFirst );
|
3444
3497
|
}
|
3445
3498
|
},
|
3446
3499
|
checkFilters: function( table, filter, skipFirst ) {
|
@@ -3454,7 +3507,7 @@
|
|
3454
3507
|
// update cache if delayInit set & pager has initialized ( after user initiates a search )
|
3455
3508
|
if ( c.delayInit && c.pager && c.pager.initialized ) {
|
3456
3509
|
c.$table.trigger( 'updateCache', [ function() {
|
3457
|
-
|
3510
|
+
tsf.checkFilters( table, false, skipFirst );
|
3458
3511
|
} ] );
|
3459
3512
|
}
|
3460
3513
|
return;
|
@@ -3485,11 +3538,11 @@
|
|
3485
3538
|
if ( c.showProcessing ) {
|
3486
3539
|
// give it time for the processing icon to kick in
|
3487
3540
|
setTimeout( function() {
|
3488
|
-
|
3541
|
+
tsf.findRows( table, filters, combinedFilters );
|
3489
3542
|
return false;
|
3490
3543
|
}, 30 );
|
3491
3544
|
} else {
|
3492
|
-
|
3545
|
+
tsf.findRows( table, filters, combinedFilters );
|
3493
3546
|
return false;
|
3494
3547
|
}
|
3495
3548
|
},
|
@@ -3532,8 +3585,8 @@
|
|
3532
3585
|
},
|
3533
3586
|
defaultFilter: function( filter, mask ) {
|
3534
3587
|
if ( filter === '' ) { return filter; }
|
3535
|
-
var regex =
|
3536
|
-
maskLen = mask.match(
|
3588
|
+
var regex = tsf.regex.iQuery,
|
3589
|
+
maskLen = mask.match( tsf.regex.igQuery ).length,
|
3537
3590
|
query = maskLen > 1 ? $.trim( filter ).split( /\s/ ) : [ $.trim( filter ) ],
|
3538
3591
|
len = query.length - 1,
|
3539
3592
|
indx = 0,
|
@@ -3569,7 +3622,10 @@
|
|
3569
3622
|
// & don't target 'all' column inputs if they don't exist
|
3570
3623
|
targets = wo.filter_initialized || !$input.filter( wo.filter_anyColumnSelector ).length,
|
3571
3624
|
columns = [],
|
3572
|
-
val = $.trim(
|
3625
|
+
val = $.trim( tsf.getLatestSearch( $input ).attr( 'data-column' ) || '' );
|
3626
|
+
if ( !/[,-]/.test(val) && val.length === 1 ) {
|
3627
|
+
return parseInt( val, 10 );
|
3628
|
+
}
|
3573
3629
|
// process column range
|
3574
3630
|
if ( targets && /-/.test( val ) ) {
|
3575
3631
|
ranges = val.match( /(\d+)\s*-\s*(\d+)/g );
|
@@ -3616,9 +3672,9 @@
|
|
3616
3672
|
var ffxn,
|
3617
3673
|
filterMatched = null,
|
3618
3674
|
matches = null;
|
3619
|
-
for ( ffxn in
|
3675
|
+
for ( ffxn in tsf.types ) {
|
3620
3676
|
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
|
3621
|
-
matches =
|
3677
|
+
matches = tsf.types[ffxn]( c, data, vars );
|
3622
3678
|
if ( matches !== null ) {
|
3623
3679
|
filterMatched = matches;
|
3624
3680
|
}
|
@@ -3627,16 +3683,23 @@
|
|
3627
3683
|
return filterMatched;
|
3628
3684
|
},
|
3629
3685
|
processRow: function( c, data, vars ) {
|
3630
|
-
var
|
3686
|
+
var hasSelect, result, val, filterMatched,
|
3631
3687
|
fxn, ffxn, txt,
|
3632
|
-
regex =
|
3688
|
+
regex = tsf.regex,
|
3633
3689
|
wo = c.widgetOptions,
|
3634
|
-
showRow = true
|
3690
|
+
showRow = true,
|
3691
|
+
|
3692
|
+
// if wo.filter_$anyMatch data-column attribute is changed dynamically
|
3693
|
+
// we don't want to do an "anyMatch" search on one column using data
|
3694
|
+
// for the entire row - see #998
|
3695
|
+
columnIndex = wo.filter_$anyMatch && wo.filter_$anyMatch.length ?
|
3696
|
+
// look for multiple columns '1-3,4-6,8'
|
3697
|
+
tsf.multipleColumns( c, wo.filter_$anyMatch ) :
|
3698
|
+
[];
|
3699
|
+
|
3635
3700
|
data.$cells = data.$row.children();
|
3636
3701
|
|
3637
|
-
if ( data.anyMatchFlag ) {
|
3638
|
-
// look for multiple columns '1-3,4-6,8'
|
3639
|
-
columnIndex = ts.filter.multipleColumns( c, wo.filter_$anyMatch );
|
3702
|
+
if ( data.anyMatchFlag && columnIndex.length > 1 ) {
|
3640
3703
|
data.anyMatch = true;
|
3641
3704
|
data.isMatch = true;
|
3642
3705
|
data.rowArray = data.$cells.map( function( i ) {
|
@@ -3660,7 +3723,7 @@
|
|
3660
3723
|
data.cache = data.cacheArray.slice( 0, -1 ).join( ' ' );
|
3661
3724
|
|
3662
3725
|
vars.excludeMatch = vars.noAnyMatch;
|
3663
|
-
filterMatched =
|
3726
|
+
filterMatched = tsf.processTypes( c, data, vars );
|
3664
3727
|
|
3665
3728
|
if ( filterMatched !== null ) {
|
3666
3729
|
showRow = filterMatched;
|
@@ -3721,7 +3784,7 @@
|
|
3721
3784
|
|
3722
3785
|
val = true;
|
3723
3786
|
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
3724
|
-
data.filter =
|
3787
|
+
data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
3725
3788
|
// val is used to indicate that a filter select is using a default filter;
|
3726
3789
|
// so we override the exact & partial matches
|
3727
3790
|
val = false;
|
@@ -3752,13 +3815,13 @@
|
|
3752
3815
|
if ( filterMatched === null ) {
|
3753
3816
|
// cycle through the different filters
|
3754
3817
|
// filters return a boolean or null if nothing matches
|
3755
|
-
filterMatched =
|
3818
|
+
filterMatched = tsf.processTypes( c, data, vars );
|
3756
3819
|
if ( filterMatched !== null ) {
|
3757
3820
|
result = filterMatched;
|
3758
3821
|
// Look for match, and add child row data for matching
|
3759
3822
|
} else {
|
3760
3823
|
txt = ( data.iExact + data.childRowText )
|
3761
|
-
.indexOf(
|
3824
|
+
.indexOf( tsf.parseFilter( c, data.iFilter, columnIndex, data.parsed[ columnIndex ] ) );
|
3762
3825
|
result = ( ( !wo.filter_startsWith && txt >= 0 ) || ( wo.filter_startsWith && txt === 0 ) );
|
3763
3826
|
}
|
3764
3827
|
} else {
|
@@ -3778,7 +3841,7 @@
|
|
3778
3841
|
isChild, childRow, lastSearch, showRow, time, val, indx,
|
3779
3842
|
notFiltered, searchFiltered, query, injected, res, id, txt,
|
3780
3843
|
storedFilters = $.extend( [], filters ),
|
3781
|
-
regex =
|
3844
|
+
regex = tsf.regex,
|
3782
3845
|
c = table.config,
|
3783
3846
|
wo = c.widgetOptions,
|
3784
3847
|
// data object passed to filters; anyMatch is a flag for the filters
|
@@ -3855,7 +3918,7 @@
|
|
3855
3918
|
data.anyMatchFlag = true;
|
3856
3919
|
data.anyMatchFilter = '' + (
|
3857
3920
|
filters[ c.columns ] ||
|
3858
|
-
wo.filter_$anyMatch &&
|
3921
|
+
wo.filter_$anyMatch && tsf.getLatestSearch( wo.filter_$anyMatch ).val() ||
|
3859
3922
|
''
|
3860
3923
|
);
|
3861
3924
|
if ( wo.filter_columnAnyMatch ) {
|
@@ -3897,10 +3960,10 @@
|
|
3897
3960
|
// if there is NOT a logical 'or', or range ( 'to' or '-' ) in the string
|
3898
3961
|
!regex.alreadyFiltered.test( val ) &&
|
3899
3962
|
// if we are not doing exact matches, using '|' ( logical or ) or not '!'
|
3900
|
-
|
3963
|
+
!regex.exactTest.test( val ) &&
|
3901
3964
|
// don't search only filtered if the value is negative
|
3902
3965
|
// ( '> -10' => '> -100' will ignore hidden rows )
|
3903
|
-
!(
|
3966
|
+
!( regex.isNeg1.test( val ) || regex.isNeg2.test( val ) ) &&
|
3904
3967
|
// if filtering using a select without a 'filter-match' class ( exact match ) - fixes #593
|
3905
3968
|
!( val !== '' && c.$filters && c.$filters.eq( indx ).find( 'select' ).length &&
|
3906
3969
|
!c.$headerIndexed[indx].hasClass( 'filter-match' ) );
|
@@ -3919,7 +3982,7 @@
|
|
3919
3982
|
data.anyMatchFilter = ts.replaceAccents( data.anyMatchFilter );
|
3920
3983
|
}
|
3921
3984
|
if ( wo.filter_defaultFilter && regex.iQuery.test( vars.defaultAnyFilter ) ) {
|
3922
|
-
data.anyMatchFilter =
|
3985
|
+
data.anyMatchFilter = tsf.defaultFilter( data.anyMatchFilter, vars.defaultAnyFilter );
|
3923
3986
|
// clear search filtered flag because default filters are not saved to the last search
|
3924
3987
|
searchFiltered = false;
|
3925
3988
|
}
|
@@ -3962,7 +4025,7 @@
|
|
3962
4025
|
'';
|
3963
4026
|
}
|
3964
4027
|
|
3965
|
-
showRow =
|
4028
|
+
showRow = tsf.processRow( c, data, vars );
|
3966
4029
|
childRow = rowData.$row.filter( ':gt( 0 )' );
|
3967
4030
|
|
3968
4031
|
if ( wo.filter_childRows && childRow.length ) {
|
@@ -3973,7 +4036,7 @@
|
|
3973
4036
|
data.cacheArray = rowData.child[ indx ];
|
3974
4037
|
data.rawArray = data.cacheArray;
|
3975
4038
|
// use OR comparison on child rows
|
3976
|
-
showRow = showRow ||
|
4039
|
+
showRow = showRow || tsf.processRow( c, data, vars );
|
3977
4040
|
}
|
3978
4041
|
}
|
3979
4042
|
childRow.toggleClass( wo.filter_filteredRow, !showRow );
|
@@ -4035,7 +4098,7 @@
|
|
4035
4098
|
}
|
4036
4099
|
if ( arry === false ) {
|
4037
4100
|
// fall back to original method
|
4038
|
-
arry =
|
4101
|
+
arry = tsf.getOptions( table, column, onlyAvail );
|
4039
4102
|
}
|
4040
4103
|
|
4041
4104
|
// get unique elements and sort the list
|
@@ -4147,13 +4210,13 @@
|
|
4147
4210
|
// nothing included in arry ( external source ), so get the options from
|
4148
4211
|
// filter_selectSource or column data
|
4149
4212
|
if ( typeof arry === 'undefined' || arry === '' ) {
|
4150
|
-
arry =
|
4213
|
+
arry = tsf.getOptionSource( table, column, onlyAvail );
|
4151
4214
|
}
|
4152
4215
|
|
4153
4216
|
if ( $.isArray( arry ) ) {
|
4154
4217
|
// build option list
|
4155
4218
|
for ( indx = 0; indx < arry.length; indx++ ) {
|
4156
|
-
txt = arry[indx] = ( '' + arry[indx] ).replace(
|
4219
|
+
txt = arry[indx] = ( '' + arry[indx] ).replace( tsf.regex.quote, '"' );
|
4157
4220
|
val = txt;
|
4158
4221
|
// allow including a symbol in the selectSource array
|
4159
4222
|
// 'a-z|A through Z' so that 'a-z' becomes the option value
|
@@ -4209,7 +4272,7 @@
|
|
4209
4272
|
// look for the filter-select class; build/update it if found
|
4210
4273
|
if ( ( $header.hasClass( 'filter-select' ) ||
|
4211
4274
|
ts.getColumnData( table, wo.filter_functions, columnIndex ) === true ) && noSelect ) {
|
4212
|
-
|
4275
|
+
tsf.buildSelect( table, columnIndex, '', updating, $header.hasClass( wo.filter_onlyAvail ) );
|
4213
4276
|
}
|
4214
4277
|
}
|
4215
4278
|
}
|
@@ -4245,7 +4308,7 @@
|
|
4245
4308
|
$column = $filters.filter( cols );
|
4246
4309
|
if ( $column.length ) {
|
4247
4310
|
// move the latest search to the first slot in the array
|
4248
|
-
$column =
|
4311
|
+
$column = tsf.getLatestSearch( $column );
|
4249
4312
|
if ( $.isArray( setFilters ) ) {
|
4250
4313
|
// skip first ( latest input ) to maintain cursor position while typing
|
4251
4314
|
if ( skipFirst && $column.length > 1 ) {
|
@@ -4295,7 +4358,7 @@
|
|
4295
4358
|
// ensure new set filters are applied, even if the search is the same
|
4296
4359
|
c.lastCombinedFilter = null;
|
4297
4360
|
c.lastSearch = [];
|
4298
|
-
|
4361
|
+
tsf.searching( c.table, filter, skipFirst );
|
4299
4362
|
c.$table.trigger( 'filterFomatterUpdate' );
|
4300
4363
|
}
|
4301
4364
|
return !!valid;
|