jquery-tablesorter 1.11.2 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/images/jquery-tablesorter/bootstrap-black-unsorted.png +0 -0
- data/vendor/assets/images/jquery-tablesorter/bootstrap-white-unsorted.png +0 -0
- data/vendor/assets/images/jquery-tablesorter/metro-black-asc.png +0 -0
- data/vendor/assets/images/jquery-tablesorter/metro-black-desc.png +0 -0
- data/vendor/assets/images/jquery-tablesorter/metro-loading.gif +0 -0
- data/vendor/assets/images/jquery-tablesorter/metro-unsorted.png +0 -0
- data/vendor/assets/images/jquery-tablesorter/metro-white-asc.png +0 -0
- data/vendor/assets/images/jquery-tablesorter/metro-white-desc.png +0 -0
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +8 -3
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +94 -29
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +103 -67
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +18 -7
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +10 -7
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +64 -25
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +45 -21
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +9 -4
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +122 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +3 -3
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.bootstrap.css +9 -3
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.green.css +10 -10
- data/vendor/assets/stylesheets/jquery-tablesorter/theme.metro-dark.css +192 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65ae3cb21c44ee0f6bfee2c97b57b137ae72b4eb
|
4
|
+
data.tar.gz: 8497edb9c98963bd4645d158c8b161467646d23a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 297953c27301fe09470785ac076576f262ed73f4c8847a2b8da5d0485e9f4bd629755b586021d5ca11a859972a950825cf0f16306de247ddedd0e30e09f1e51a
|
7
|
+
data.tar.gz: 9c2d2ee68462a3c05b1a35c9294bd0fd4c2d22daf20949aed52dc1d37e133ea4f4b541f0cb7fa4d6503d6fa7132605de69597b798dc65865c212b0376c8c0234
|
data/README.md
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
|
5
5
|
Simple integration of jquery-tablesorter into the asset pipeline.
|
6
6
|
|
7
|
-
Current tablesorter version: 2.
|
7
|
+
Current tablesorter version: 2.17.0 (5/22/2014), [documentation]
|
8
8
|
|
9
|
-
Any issue
|
9
|
+
Any issue associated with the js/css files, please report to [Mottie's fork].
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
* tablesorter pager plugin
|
3
|
-
* updated
|
3
|
+
* updated 5/22/2014 (v2.17.0)
|
4
4
|
*/
|
5
5
|
/*jshint browser:true, jquery:true, unused:false */
|
6
6
|
;(function($) {
|
@@ -289,7 +289,7 @@
|
|
289
289
|
exception === 'timeout' ? 'Time out error' :
|
290
290
|
exception === 'abort' ? 'Ajax Request aborted' :
|
291
291
|
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
|
292
|
-
c.$tbodies.eq(0).
|
292
|
+
c.$tbodies.eq(0).detach();
|
293
293
|
p.totalRows = 0;
|
294
294
|
} else {
|
295
295
|
// process ajax object
|
@@ -311,7 +311,7 @@
|
|
311
311
|
if (d instanceof jQuery) {
|
312
312
|
if (p.processAjaxOnInit) {
|
313
313
|
// append jQuery object
|
314
|
-
c.$tbodies.eq(0).
|
314
|
+
c.$tbodies.eq(0).detach().append(d);
|
315
315
|
}
|
316
316
|
} else if (l) {
|
317
317
|
// build table from array
|
@@ -726,6 +726,11 @@
|
|
726
726
|
})
|
727
727
|
.bind('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){
|
728
728
|
e.stopPropagation();
|
729
|
+
fixHeight(table, p);
|
730
|
+
var $rows = c.$tbodies.eq(0).children();
|
731
|
+
p.totalRows = $rows.length - ( p.countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
|
732
|
+
p.totalPages = Math.ceil( p.totalRows / p.size );
|
733
|
+
updatePageDisplay(table, p);
|
729
734
|
hideRows(table, p);
|
730
735
|
})
|
731
736
|
.bind('pageSize.pager', function(e,v){
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**!
|
2
|
-
* TableSorter 2.
|
2
|
+
* TableSorter 2.17.0 - Client-side table sorting with ease!
|
3
3
|
* @requires jQuery v1.2.6+
|
4
4
|
*
|
5
5
|
* Copyright (c) 2007 Christian Bach
|
@@ -24,7 +24,7 @@
|
|
24
24
|
|
25
25
|
var ts = this;
|
26
26
|
|
27
|
-
ts.version = "2.
|
27
|
+
ts.version = "2.17.0";
|
28
28
|
|
29
29
|
ts.parsers = [];
|
30
30
|
ts.widgets = [];
|
@@ -167,7 +167,7 @@
|
|
167
167
|
|
168
168
|
function getElementText(table, node, cellIndex) {
|
169
169
|
if (!node) { return ""; }
|
170
|
-
var c = table.config,
|
170
|
+
var te, c = table.config,
|
171
171
|
t = c.textExtraction || '',
|
172
172
|
text = "";
|
173
173
|
if (t === "basic") {
|
@@ -176,8 +176,8 @@
|
|
176
176
|
} else {
|
177
177
|
if (typeof(t) === "function") {
|
178
178
|
text = t(node, table, cellIndex);
|
179
|
-
} else if (typeof(
|
180
|
-
text =
|
179
|
+
} else if (typeof (te = ts.getColumnData( table, t, cellIndex )) === 'function') {
|
180
|
+
text = te(node, table, cellIndex);
|
181
181
|
} else {
|
182
182
|
// previous "simple" method
|
183
183
|
text = node.textContent || node.innerText || $(node).text() || "";
|
@@ -219,7 +219,7 @@
|
|
219
219
|
var c = table.config,
|
220
220
|
// update table bodies in case we start with an empty table
|
221
221
|
tb = c.$tbodies = c.$table.children('tbody:not(.' + c.cssInfoBlock + ')'),
|
222
|
-
rows, list, l, i, h, ch, p, time,
|
222
|
+
rows, list, l, i, h, ch, p, time,
|
223
223
|
j = 0,
|
224
224
|
parsersDebug = "",
|
225
225
|
len = tb.length;
|
@@ -233,16 +233,11 @@
|
|
233
233
|
while (j < len) {
|
234
234
|
rows = tb[j].rows;
|
235
235
|
if (rows[j]) {
|
236
|
-
l = rows[j].cells.length;
|
236
|
+
l = c.columns; // rows[j].cells.length;
|
237
237
|
for (i = 0; i < l; i++) {
|
238
|
-
|
239
|
-
//
|
240
|
-
|
241
|
-
h = h.add( c.$headers.filter('[colspan="1"]') ) // ie8 fix
|
242
|
-
.filter('[data-column="' + i + '"]:last');
|
243
|
-
// get headers option corrected index
|
244
|
-
indx = c.$headers.index(h);
|
245
|
-
ch = c.headers[indx];
|
238
|
+
h = c.$headers.filter('[data-column="' + i + '"]:last');
|
239
|
+
// get column indexed table cell
|
240
|
+
ch = ts.getColumnData( table, c.headers, i );
|
246
241
|
// get column parser
|
247
242
|
p = ts.getParserById( ts.getData(h, ch, 'sorter') );
|
248
243
|
// empty cells behaviour - keeping emptyToBottom for backwards compatibility
|
@@ -421,10 +416,12 @@
|
|
421
416
|
c.columns = ts.computeColumnIndex( c.$table.children('thead, tfoot').children('tr') );
|
422
417
|
// add icon if cssIcon option exists
|
423
418
|
i = c.cssIcon ? '<i class="' + ( c.cssIcon === ts.css.icon ? ts.css.icon : c.cssIcon + ' ' + ts.css.icon ) + '"></i>' : '';
|
424
|
-
c.$headers
|
419
|
+
c.$headers.each(function(index) {
|
425
420
|
$t = $(this);
|
426
|
-
|
427
|
-
|
421
|
+
// make sure to get header cell & not column indexed cell
|
422
|
+
ch = ts.getColumnData( table, c.headers, index, true );
|
423
|
+
// save original header content
|
424
|
+
c.headerContent[index] = $(this).html();
|
428
425
|
// set up header template
|
429
426
|
t = c.headerTemplate.replace(/\{content\}/g, $(this).html()).replace(/\{icon\}/g, i);
|
430
427
|
if (c.onRenderTemplate) {
|
@@ -473,10 +470,11 @@
|
|
473
470
|
}
|
474
471
|
|
475
472
|
function updateHeader(table) {
|
476
|
-
var s, $th,
|
473
|
+
var s, $th,
|
474
|
+
c = table.config;
|
477
475
|
c.$headers.each(function(index, th){
|
478
476
|
$th = $(th);
|
479
|
-
s = ts.getData( th, c.headers
|
477
|
+
s = ts.getData( th, ts.getColumnData( table, c.headers, index, true ), 'sorter' ) === 'false';
|
480
478
|
th.sortDisabled = s;
|
481
479
|
$th[ s ? 'addClass' : 'removeClass' ]('sorter-false').attr('aria-disabled', '' + s);
|
482
480
|
// aria-controls - requires table ID
|
@@ -546,19 +544,46 @@
|
|
546
544
|
}
|
547
545
|
}
|
548
546
|
|
549
|
-
function updateHeaderSortCount(table, list
|
550
|
-
var s, t, o,
|
547
|
+
function updateHeaderSortCount(table, list) {
|
548
|
+
var s, t, o, col, primary,
|
549
|
+
c = table.config,
|
551
550
|
sl = list || c.sortList;
|
552
551
|
c.sortList = [];
|
553
552
|
$.each(sl, function(i,v){
|
554
553
|
// ensure all sortList values are numeric - fixes #127
|
555
|
-
|
554
|
+
col = parseInt(v[0], 10);
|
556
555
|
// make sure header exists
|
557
|
-
o = c.$headers.filter('[data-column="' +
|
556
|
+
o = c.$headers.filter('[data-column="' + col + '"]:last')[0];
|
558
557
|
if (o) { // prevents error if sorton array is wrong
|
558
|
+
// o.count = o.count + 1;
|
559
|
+
t = ('' + v[1]).match(/^(1|d|s|o|n)/);
|
560
|
+
t = t ? t[0] : '';
|
561
|
+
// 0/(a)sc (default), 1/(d)esc, (s)ame, (o)pposite, (n)ext
|
562
|
+
switch(t) {
|
563
|
+
case '1': case 'd': // descending
|
564
|
+
t = 1;
|
565
|
+
break;
|
566
|
+
case 's': // same direction (as primary column)
|
567
|
+
// if primary sort is set to "s", make it ascending
|
568
|
+
t = primary || 0;
|
569
|
+
break;
|
570
|
+
case 'o':
|
571
|
+
s = o.order[(primary || 0) % (c.sortReset ? 3 : 2)];
|
572
|
+
// opposite of primary column; but resets if primary resets
|
573
|
+
t = s === 0 ? 1 : s === 1 ? 0 : 2;
|
574
|
+
break;
|
575
|
+
case 'n':
|
576
|
+
o.count = o.count + 1;
|
577
|
+
t = o.order[(o.count) % (c.sortReset ? 3 : 2)];
|
578
|
+
break;
|
579
|
+
default: // ascending
|
580
|
+
t = 0;
|
581
|
+
break;
|
582
|
+
}
|
583
|
+
primary = i === 0 ? t : primary;
|
584
|
+
s = [ col, parseInt(t, 10) || 0 ];
|
559
585
|
c.sortList.push(s);
|
560
586
|
t = $.inArray(s[1], o.order); // fixes issue #167
|
561
|
-
if (triggered) { o.count = o.count + 1; }
|
562
587
|
o.count = t >= 0 ? t : s[1] % (c.sortReset ? 3 : 2);
|
563
588
|
}
|
564
589
|
});
|
@@ -872,7 +897,7 @@
|
|
872
897
|
e.stopPropagation();
|
873
898
|
$table.trigger("sortStart", this);
|
874
899
|
// update header count index
|
875
|
-
updateHeaderSortCount(table, list
|
900
|
+
updateHeaderSortCount(table, list);
|
876
901
|
// set css for headers
|
877
902
|
setHeadersCss(table);
|
878
903
|
// fixes #346
|
@@ -921,6 +946,16 @@
|
|
921
946
|
.bind("destroy" + c.namespace, function(e, c, cb){
|
922
947
|
e.stopPropagation();
|
923
948
|
ts.destroy(table, c, cb);
|
949
|
+
})
|
950
|
+
.bind("resetToLoadState" + c.namespace, function(e){
|
951
|
+
// remove all widgets
|
952
|
+
ts.refreshWidgets(table, true, true);
|
953
|
+
// restore original settings; this clears out current settings, but does not clear
|
954
|
+
// values saved to storage.
|
955
|
+
c = $.extend(true, ts.defaults, c.originalSettings);
|
956
|
+
table.hasInitialized = false;
|
957
|
+
// setup the entire table again
|
958
|
+
ts.setup( table, c );
|
924
959
|
});
|
925
960
|
}
|
926
961
|
|
@@ -930,6 +965,8 @@
|
|
930
965
|
var table = this,
|
931
966
|
// merge & extend config options
|
932
967
|
c = $.extend(true, {}, ts.defaults, settings);
|
968
|
+
// save initial settings
|
969
|
+
c.originalSettings = settings;
|
933
970
|
// create a table from data (build table widget)
|
934
971
|
if (!table.hasInitialized && ts.buildTable && this.tagName !== 'TABLE') {
|
935
972
|
// return the table (in case the original target is the table's container)
|
@@ -973,6 +1010,7 @@
|
|
973
1010
|
c.$table = $table
|
974
1011
|
.addClass(ts.css.table + ' ' + c.tableClass + k)
|
975
1012
|
.attr({ role : 'grid'});
|
1013
|
+
c.$headers = $(table).find(c.selectorHeaders);
|
976
1014
|
|
977
1015
|
// give the table a unique id, which will be used in namespace binding
|
978
1016
|
if (!c.namespace) {
|
@@ -1050,6 +1088,31 @@
|
|
1050
1088
|
if (typeof c.initialized === 'function') { c.initialized(table); }
|
1051
1089
|
};
|
1052
1090
|
|
1091
|
+
ts.getColumnData = function(table, obj, indx, getCell){
|
1092
|
+
if (typeof obj === 'undefined' || obj === null) { return; }
|
1093
|
+
table = $(table)[0];
|
1094
|
+
var result, $h, k,
|
1095
|
+
c = table.config;
|
1096
|
+
if (obj[indx]) {
|
1097
|
+
return getCell ? obj[indx] : obj[c.$headers.index( c.$headers.filter('[data-column="' + indx + '"]:last') )];
|
1098
|
+
}
|
1099
|
+
for (k in obj) {
|
1100
|
+
if (typeof k === 'string') {
|
1101
|
+
if (getCell) {
|
1102
|
+
// get header cell
|
1103
|
+
$h = c.$headers.eq(indx).filter(k);
|
1104
|
+
} else {
|
1105
|
+
// get column indexed cell
|
1106
|
+
$h = c.$headers.filter('[data-column="' + indx + '"]:last').filter(k);
|
1107
|
+
}
|
1108
|
+
if ($h.length) {
|
1109
|
+
return obj[k];
|
1110
|
+
}
|
1111
|
+
}
|
1112
|
+
}
|
1113
|
+
return result;
|
1114
|
+
};
|
1115
|
+
|
1053
1116
|
// computeTableHeaderCellIndexes from:
|
1054
1117
|
// http://www.javascripttoolbox.com/lib/table/examples.php
|
1055
1118
|
// http://www.javascripttoolbox.com/temp/table_cellindex.html
|
@@ -1136,7 +1199,7 @@
|
|
1136
1199
|
};
|
1137
1200
|
|
1138
1201
|
ts.clearTableBody = function(table) {
|
1139
|
-
$(table)[0].config.$tbodies.
|
1202
|
+
$(table)[0].config.$tbodies.detach();
|
1140
1203
|
};
|
1141
1204
|
|
1142
1205
|
ts.bindEvents = function(table, $headers, core){
|
@@ -1217,7 +1280,7 @@
|
|
1217
1280
|
// disable tablesorter
|
1218
1281
|
$t
|
1219
1282
|
.removeData('tablesorter')
|
1220
|
-
.unbind('sortReset update updateAll updateRows updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd '.split(' ').join(c.namespace + ' '));
|
1283
|
+
.unbind('sortReset update updateAll updateRows updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd resetToLoadState '.split(' ').join(c.namespace + ' '));
|
1221
1284
|
c.$headers.add($f)
|
1222
1285
|
.removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone].join(' ') )
|
1223
1286
|
.removeAttr('data-column')
|
@@ -1403,6 +1466,8 @@
|
|
1403
1466
|
};
|
1404
1467
|
|
1405
1468
|
ts.getParserById = function(name) {
|
1469
|
+
/*jshint eqeqeq:false */
|
1470
|
+
if (name == 'false') { return false; }
|
1406
1471
|
var i, l = ts.parsers.length;
|
1407
1472
|
for (i = 0; i < l; i++) {
|
1408
1473
|
if (ts.parsers[i].id.toLowerCase() === (name.toString()).toLowerCase()) {
|
@@ -1678,7 +1743,7 @@
|
|
1678
1743
|
if (s) {
|
1679
1744
|
var c = table.config,
|
1680
1745
|
ci = c.$headers.filter('[data-column=' + cellIndex + ']:last'),
|
1681
|
-
format = ci.length && ci[0].dateFormat || ts.getData( ci, c.headers
|
1746
|
+
format = ci.length && ci[0].dateFormat || ts.getData( ci, ts.getColumnData( table, c.headers, cellIndex ), 'dateFormat') || c.dateFormat;
|
1682
1747
|
s = s.replace(/\s+/g," ").replace(/[\-.,]/g, "/"); // escaped - because JSHint in Firefox was showing it as an error
|
1683
1748
|
if (format === "mmddyyyy") {
|
1684
1749
|
s = s.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/, "$3/$1/$2");
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! tableSorter 2.16+ widgets - updated
|
1
|
+
/*! tableSorter 2.16+ widgets - updated 5/22/2014 (v2.17.0)
|
2
2
|
*
|
3
3
|
* Column Styles
|
4
4
|
* Column Filters
|
@@ -438,16 +438,18 @@ ts.filter = {
|
|
438
438
|
query = ts.formatFloat( iFilter.replace(ts.filter.regex.operators, ''), table ),
|
439
439
|
parser = c.parsers[index],
|
440
440
|
savedSearch = query;
|
441
|
-
|
441
|
+
// parse filter value in case we're comparing numbers (dates)
|
442
442
|
if (parsed[index] || parser.type === 'numeric') {
|
443
|
-
|
444
|
-
query = ( typeof
|
443
|
+
result = parser.format( $.trim('' + iFilter.replace(ts.filter.regex.operators, '')), table, [], index );
|
444
|
+
query = ( typeof result === "number" && result !== '' && !isNaN(result) ) ? result : query;
|
445
445
|
}
|
446
|
+
|
446
447
|
// iExact may be numeric - see issue #149;
|
447
448
|
// check if cached is defined, because sometimes j goes out of range? (numeric columns)
|
448
|
-
cachedValue = ( parsed[index] || parser.type === 'numeric' ) && !isNaN(query) && cached ? cached :
|
449
|
+
cachedValue = ( parsed[index] || parser.type === 'numeric' ) && !isNaN(query) && typeof cached !== 'undefined' ? cached :
|
449
450
|
isNaN(iExact) ? ts.formatFloat( iExact.replace(ts.filter.regex.nondigit, ''), table) :
|
450
451
|
ts.formatFloat( iExact, table );
|
452
|
+
|
451
453
|
if ( />/.test(iFilter) ) { result = />=/.test(iFilter) ? cachedValue >= query : cachedValue > query; }
|
452
454
|
if ( /</.test(iFilter) ) { result = /<=/.test(iFilter) ? cachedValue <= query : cachedValue < query; }
|
453
455
|
// keep showing all rows if nothing follows the operator
|
@@ -476,8 +478,8 @@ ts.filter = {
|
|
476
478
|
},
|
477
479
|
// Look for an AND or && operator (logical and)
|
478
480
|
and : function( filter, iFilter, exact, iExact ) {
|
479
|
-
if (
|
480
|
-
var query = iFilter.split(
|
481
|
+
if ( ts.filter.regex.andTest.test(filter) ) {
|
482
|
+
var query = iFilter.split( ts.filter.regex.andSplit ),
|
481
483
|
result = iExact.search( $.trim(query[0]) ) >= 0,
|
482
484
|
indx = query.length - 1;
|
483
485
|
while (result && indx) {
|
@@ -490,10 +492,11 @@ ts.filter = {
|
|
490
492
|
},
|
491
493
|
// Look for a range (using " to " or " - ") - see issue #166; thanks matzhu!
|
492
494
|
range : function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed ) {
|
493
|
-
if (
|
495
|
+
if ( ts.filter.regex.toTest.test(iFilter) ) {
|
494
496
|
var result, tmp,
|
495
497
|
c = table.config,
|
496
|
-
|
498
|
+
// make sure the dash is for a range and not indicating a negative number
|
499
|
+
query = iFilter.split( ts.filter.regex.toSplit ),
|
497
500
|
range1 = ts.formatFloat(query[0].replace(ts.filter.regex.nondigit, ''), table),
|
498
501
|
range2 = ts.formatFloat(query[1].replace(ts.filter.regex.nondigit, ''), table);
|
499
502
|
// parse filter value in case we're comparing numbers (dates)
|
@@ -513,9 +516,9 @@ ts.filter = {
|
|
513
516
|
},
|
514
517
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
515
518
|
wild : function( filter, iFilter, exact, iExact, cached, index, table, wo, parsed, rowArray ) {
|
516
|
-
if ( /[\?|\*]/.test(iFilter) ||
|
519
|
+
if ( /[\?|\*]/.test(iFilter) || ts.filter.regex.orReplace.test(filter) ) {
|
517
520
|
var c = table.config,
|
518
|
-
query = iFilter.replace(
|
521
|
+
query = iFilter.replace(ts.filter.regex.orReplace, "|");
|
519
522
|
// look for an exact match with the "or" unless the "filter-match" class is found
|
520
523
|
if (!c.$headers.filter('[data-column="' + index + '"]:last').hasClass('filter-match') && /\|/.test(query)) {
|
521
524
|
query = $.isArray(rowArray) ? '(' + query + ')' : '^(' + query + ')$';
|
@@ -545,14 +548,30 @@ ts.filter = {
|
|
545
548
|
}
|
546
549
|
},
|
547
550
|
init: function(table, c, wo) {
|
548
|
-
|
551
|
+
// filter language options
|
552
|
+
ts.language = $.extend(true, {}, {
|
553
|
+
to : 'to',
|
554
|
+
or : 'or',
|
555
|
+
and : 'and'
|
556
|
+
}, ts.language);
|
557
|
+
|
558
|
+
var options, string, $header, column, filters, time, fxn,
|
559
|
+
regex = ts.filter.regex;
|
549
560
|
if (c.debug) {
|
550
561
|
time = new Date();
|
551
562
|
}
|
552
563
|
c.$table.addClass('hasFilters');
|
553
564
|
|
554
|
-
|
555
|
-
|
565
|
+
$.extend( regex, {
|
566
|
+
child : new RegExp(c.cssChildRow),
|
567
|
+
filtered : new RegExp(wo.filter_filteredRow),
|
568
|
+
alreadyFiltered : new RegExp('(\\s+(' + ts.language.or + '|-|' + ts.language.to + ')\\s+)', 'i'),
|
569
|
+
toTest : new RegExp('\\s+(-|' + ts.language.to + ')\\s+', 'i'),
|
570
|
+
toSplit : new RegExp('(?:\\s+(?:-|' + ts.language.to + ')\\s+)' ,'gi'),
|
571
|
+
andTest : new RegExp('\\s+(' + ts.language.and + '|&&)\\s+', 'i'),
|
572
|
+
andSplit : new RegExp('(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi'),
|
573
|
+
orReplace : new RegExp('\\s+(' + ts.language.or + ')\\s+', 'gi')
|
574
|
+
});
|
556
575
|
|
557
576
|
// don't build filter row if columnFilters is false or all columns are set to "filter-false" - issue #156
|
558
577
|
if (wo.filter_columnFilters !== false && c.$headers.filter('.filter-false').length !== c.$headers.length) {
|
@@ -576,6 +595,7 @@ ts.filter = {
|
|
576
595
|
if (/(update|add)/.test(event.type) && event.type !== "updateComplete") {
|
577
596
|
// force a new search since content has changed
|
578
597
|
c.lastCombinedFilter = null;
|
598
|
+
c.lastSearch = [];
|
579
599
|
}
|
580
600
|
// pass true (skipFirst) to prevent the tablesorter.setFilters function from skipping the first input
|
581
601
|
// ensures all inputs are updated when a search is triggered on the table $('table').trigger('search', [...]);
|
@@ -602,16 +622,16 @@ ts.filter = {
|
|
602
622
|
}
|
603
623
|
}
|
604
624
|
if (wo.filter_functions) {
|
605
|
-
|
606
|
-
|
607
|
-
if (
|
625
|
+
for (column = 0; column < c.columns; column++) {
|
626
|
+
fxn = ts.getColumnData( table, wo.filter_functions, column );
|
627
|
+
if (fxn) {
|
608
628
|
$header = c.$headers.filter('[data-column="' + column + '"]:last');
|
609
629
|
options = '';
|
610
|
-
if (
|
630
|
+
if (fxn === true && !$header.hasClass('filter-false')) {
|
611
631
|
ts.filter.buildSelect(table, column);
|
612
|
-
} else if (typeof
|
632
|
+
} else if (typeof fxn === 'object' && !$header.hasClass('filter-false')) {
|
613
633
|
// add custom drop down list
|
614
|
-
for (string in
|
634
|
+
for (string in fxn) {
|
615
635
|
if (typeof string === 'string') {
|
616
636
|
options += options === '' ?
|
617
637
|
'<option value="">' + ($header.data('placeholder') || $header.attr('data-placeholder') || wo.filter_placeholder.select || '') + '</option>' : '';
|
@@ -683,7 +703,7 @@ ts.filter = {
|
|
683
703
|
return filters;
|
684
704
|
},
|
685
705
|
buildRow: function(table, c, wo) {
|
686
|
-
var column, $header, buildSelect, disabled, name,
|
706
|
+
var column, $header, buildSelect, disabled, name, ffxn,
|
687
707
|
// c.columns defined in computeThIndexes()
|
688
708
|
columns = c.columns,
|
689
709
|
buildFilter = '<tr class="' + ts.css.filterRow + '">';
|
@@ -696,22 +716,18 @@ ts.filter = {
|
|
696
716
|
disabled = false;
|
697
717
|
// assuming last cell of a column is the main column
|
698
718
|
$header = c.$headers.filter('[data-column="' + column + '"]:last');
|
699
|
-
|
719
|
+
ffxn = ts.getColumnData( table, wo.filter_functions, column );
|
720
|
+
buildSelect = (wo.filter_functions && ffxn && typeof ffxn !== "function" ) ||
|
700
721
|
$header.hasClass('filter-select');
|
701
722
|
// get data from jQuery data, metadata, headers option or header class name
|
702
|
-
|
703
|
-
|
704
|
-
disabled = ts.getData($header[0], c.headers[column], 'filter') === 'false';
|
705
|
-
} else {
|
706
|
-
// only class names and header options - keep this for compatibility with tablesorter v2.0.5
|
707
|
-
disabled = (c.headers[column] && c.headers[column].hasOwnProperty('filter') && c.headers[column].filter === false) ||
|
708
|
-
$header.hasClass('filter-false');
|
709
|
-
}
|
723
|
+
disabled = ts.getData($header[0], ts.getColumnData( table, c.headers, column ), 'filter') === 'false';
|
724
|
+
|
710
725
|
if (buildSelect) {
|
711
726
|
buildFilter = $('<select>').appendTo( c.$filters.eq(column) );
|
712
727
|
} else {
|
713
|
-
|
714
|
-
|
728
|
+
ffxn = ts.getColumnData( table, wo.filter_formatter, column );
|
729
|
+
if (ffxn) {
|
730
|
+
buildFilter = ffxn( c.$filters.eq(column), column );
|
715
731
|
// no element returned, so lets go find it
|
716
732
|
if (buildFilter && buildFilter.length === 0) {
|
717
733
|
buildFilter = c.$filters.eq(column).children('input');
|
@@ -761,7 +777,7 @@ ts.filter = {
|
|
761
777
|
$el
|
762
778
|
// use data attribute instead of jQuery data since the head is cloned without including the data/binding
|
763
779
|
.attr('data-lastSearchTime', new Date().getTime())
|
764
|
-
.unbind('keyup search change '.split(' ').join(c.namespace + 'filter '))
|
780
|
+
.unbind('keypress keyup search change '.split(' ').join(c.namespace + 'filter '))
|
765
781
|
// include change for select - fixes #473
|
766
782
|
.bind('keyup search change '.split(' ').join(c.namespace + 'filter '), function(event) {
|
767
783
|
$(this).attr('data-lastSearchTime', new Date().getTime());
|
@@ -774,8 +790,14 @@ ts.filter = {
|
|
774
790
|
( event.which >= 37 && event.which <= 40 ) || (event.which !== 13 && wo.filter_liveSearch === false) ) ) ) {
|
775
791
|
return;
|
776
792
|
}
|
777
|
-
// true flag tells getFilters to skip newest timed input
|
778
|
-
ts.filter.searching( table,
|
793
|
+
// change event = no delay; last true flag tells getFilters to skip newest timed input
|
794
|
+
ts.filter.searching( table, event.type !== 'change', true );
|
795
|
+
})
|
796
|
+
.bind('keypress.' + c.namespace + 'filter', function(event){
|
797
|
+
if (event.which === 13) {
|
798
|
+
event.preventDefault();
|
799
|
+
$(this).blur();
|
800
|
+
}
|
779
801
|
});
|
780
802
|
c.$table.bind('filterReset', function(){
|
781
803
|
$el.val('');
|
@@ -787,6 +809,8 @@ ts.filter = {
|
|
787
809
|
filterArray = $.isArray(filter),
|
788
810
|
filters = (filterArray) ? filter : ts.getFilters(table, true),
|
789
811
|
combinedFilters = (filters || []).join(''); // combined filter values
|
812
|
+
// prevent errors if delay init is set
|
813
|
+
if ($.isEmptyObject(c.cache)) { return; }
|
790
814
|
// add filter array back into inputs
|
791
815
|
if (filterArray) {
|
792
816
|
ts.setFilters( table, filters, false, skipFirst !== true );
|
@@ -802,6 +826,7 @@ ts.filter = {
|
|
802
826
|
} else if (filter === false) {
|
803
827
|
// force filter refresh
|
804
828
|
c.lastCombinedFilter = null;
|
829
|
+
c.lastSearch = [];
|
805
830
|
}
|
806
831
|
c.$table.trigger('filterStart', [filters]);
|
807
832
|
if (c.showProcessing) {
|
@@ -856,8 +881,9 @@ ts.filter = {
|
|
856
881
|
if (table.config.lastCombinedFilter === combinedFilters) { return; }
|
857
882
|
var cached, len, $rows, rowIndex, tbodyIndex, $tbody, $cells, columnIndex,
|
858
883
|
childRow, childRowText, exact, iExact, iFilter, lastSearch, matches, result,
|
859
|
-
notFiltered, searchFiltered, filterMatched, showRow, time,
|
860
|
-
anyMatch, iAnyMatch, rowArray, rowText, iRowText, rowCache,
|
884
|
+
notFiltered, searchFiltered, filterMatched, showRow, time, val, indx,
|
885
|
+
anyMatch, iAnyMatch, rowArray, rowText, iRowText, rowCache, fxn,
|
886
|
+
regex = ts.filter.regex,
|
861
887
|
c = table.config,
|
862
888
|
wo = c.widgetOptions,
|
863
889
|
columns = c.columns,
|
@@ -868,7 +894,7 @@ ts.filter = {
|
|
868
894
|
parsed = c.$headers.map(function(columnIndex) {
|
869
895
|
return c.parsers && c.parsers[columnIndex] && c.parsers[columnIndex].parsed ||
|
870
896
|
// getData won't return "parsed" if other "filter-" class names exist (e.g. <th class="filter-select filter-parsed">)
|
871
|
-
ts.getData && ts.getData(c.$headers.filter('[data-column="' + columnIndex + '"]:last'), c.headers
|
897
|
+
ts.getData && ts.getData(c.$headers.filter('[data-column="' + columnIndex + '"]:last'), ts.getColumnData( table, c.headers, columnIndex ), 'filter') === 'parsed' ||
|
872
898
|
$(this).hasClass('filter-parsed');
|
873
899
|
}).get();
|
874
900
|
if (c.debug) { time = new Date(); }
|
@@ -879,26 +905,34 @@ ts.filter = {
|
|
879
905
|
// $rows = $tbody.children('tr').not(c.selectorRemove);
|
880
906
|
columnIndex = c.columns;
|
881
907
|
// convert stored rows into a jQuery object
|
882
|
-
$rows =
|
883
|
-
|
908
|
+
$rows = $( $.map(c.cache[tbodyIndex].normalized, function(el){ return el[columnIndex].$row.get(); }) );
|
909
|
+
|
884
910
|
if (combinedFilters === '' || wo.filter_serversideFiltering) {
|
885
911
|
$rows.removeClass(wo.filter_filteredRow).not('.' + c.cssChildRow).show();
|
886
912
|
} else {
|
913
|
+
// filter out child rows
|
914
|
+
$rows = $rows.not('.' + c.cssChildRow);
|
915
|
+
len = $rows.length;
|
887
916
|
// optimize searching only through already filtered rows - see #313
|
888
917
|
searchFiltered = true;
|
889
918
|
lastSearch = c.lastSearch || c.$table.data('lastSearch') || [];
|
890
|
-
|
919
|
+
for (indx = 0; indx < columnIndex; indx++) {
|
920
|
+
val = filters[indx] || '';
|
921
|
+
// break out of loop if we've already determined not to search filtered rows
|
922
|
+
if (!searchFiltered) { indx = columnIndex; }
|
891
923
|
// search already filtered rows if...
|
892
|
-
searchFiltered = searchFiltered &&
|
893
|
-
// there are changes from beginning of filter
|
894
|
-
|
895
|
-
// if there is
|
896
|
-
|
897
|
-
// if we are not doing exact matches
|
898
|
-
!/[=\"]/.test(
|
924
|
+
searchFiltered = searchFiltered && lastSearch.length &&
|
925
|
+
// there are no changes from beginning of filter
|
926
|
+
val.indexOf(lastSearch[indx] || '') === 0 &&
|
927
|
+
// if there is NOT a logical "or", or range ("to" or "-") in the string
|
928
|
+
!regex.alreadyFiltered.test(val) &&
|
929
|
+
// if we are not doing exact matches, using "|" (logical or) or not "!"
|
930
|
+
!/[=\"\|!]/.test(val) &&
|
931
|
+
// don't search only filtered if the value is negative ('> -10' => '> -100' will ignore hidden rows)
|
932
|
+
!(/(>=?\s*-\d)/.test(val) || /(<=?\s*\d)/.test(val)) &&
|
899
933
|
// if filtering using a select without a "filter-match" class (exact match) - fixes #593
|
900
|
-
!( val !== '' &&
|
901
|
-
}
|
934
|
+
!( val !== '' && c.$filters && c.$filters.eq(indx).find('select').length && !c.$headers.filter('[data-column="' + indx + '"]:last').hasClass('filter-match') );
|
935
|
+
}
|
902
936
|
notFiltered = $rows.not('.' + wo.filter_filteredRow).length;
|
903
937
|
// can't search when all rows are hidden - this happens when looking for exact matches
|
904
938
|
if (searchFiltered && notFiltered === 0) { searchFiltered = false; }
|
@@ -917,7 +951,7 @@ ts.filter = {
|
|
917
951
|
for (rowIndex = 0; rowIndex < len; rowIndex++) {
|
918
952
|
childRow = $rows[rowIndex].className;
|
919
953
|
// skip child rows & already filtered rows
|
920
|
-
if (
|
954
|
+
if ( regex.child.test(childRow) || (searchFiltered && regex.filtered.test(childRow)) ) { continue; }
|
921
955
|
showRow = true;
|
922
956
|
// *** nextAll/nextUntil not supported by Zepto! ***
|
923
957
|
childRow = $rows.eq(rowIndex).nextUntil('tr:not(.' + c.cssChildRow + ')');
|
@@ -973,24 +1007,25 @@ ts.filter = {
|
|
973
1007
|
exact = $.trim($cells.eq(columnIndex).text());
|
974
1008
|
exact = c.sortLocaleCompare ? ts.replaceAccents(exact) : exact; // issue #405
|
975
1009
|
}
|
976
|
-
iExact = !
|
1010
|
+
iExact = !regex.type.test(typeof exact) && wo.filter_ignoreCase ? exact.toLocaleLowerCase() : exact;
|
977
1011
|
result = showRow; // if showRow is true, show that row
|
978
1012
|
|
979
1013
|
// replace accents - see #357
|
980
1014
|
filters[columnIndex] = c.sortLocaleCompare ? ts.replaceAccents(filters[columnIndex]) : filters[columnIndex];
|
981
1015
|
// val = case insensitive, filters[columnIndex] = case sensitive
|
982
1016
|
iFilter = wo.filter_ignoreCase ? (filters[columnIndex] || '').toLocaleLowerCase() : filters[columnIndex];
|
983
|
-
|
984
|
-
|
1017
|
+
fxn = ts.getColumnData( table, wo.filter_functions, columnIndex );
|
1018
|
+
if (fxn) {
|
1019
|
+
if (fxn === true) {
|
985
1020
|
// default selector; no "filter-select" class
|
986
1021
|
result = (c.$headers.filter('[data-column="' + columnIndex + '"]:last').hasClass('filter-match')) ?
|
987
1022
|
iExact.search(iFilter) >= 0 : filters[columnIndex] === exact;
|
988
|
-
} else if (typeof
|
1023
|
+
} else if (typeof fxn === 'function') {
|
989
1024
|
// filter callback( exact cell content, parser normalized content, filter input value, column index, jQuery row object )
|
990
|
-
result =
|
991
|
-
} else if (typeof
|
1025
|
+
result = fxn(exact, cached, filters[columnIndex], columnIndex, $rows.eq(rowIndex));
|
1026
|
+
} else if (typeof fxn[filters[columnIndex]] === 'function') {
|
992
1027
|
// selector option function
|
993
|
-
result =
|
1028
|
+
result = fxn[filters[columnIndex]](exact, cached, filters[columnIndex], columnIndex, $rows.eq(rowIndex));
|
994
1029
|
}
|
995
1030
|
} else {
|
996
1031
|
filterMatched = null;
|
@@ -1044,15 +1079,16 @@ ts.filter = {
|
|
1044
1079
|
wo = c.widgetOptions,
|
1045
1080
|
parsed = [],
|
1046
1081
|
arry = false,
|
1047
|
-
source = wo.filter_selectSource
|
1082
|
+
source = wo.filter_selectSource,
|
1083
|
+
fxn = $.isFunction(source) ? true : ts.getColumnData( table, source, column );
|
1048
1084
|
|
1049
1085
|
// filter select source option
|
1050
|
-
if (
|
1086
|
+
if (fxn === true) {
|
1051
1087
|
// OVERALL source
|
1052
1088
|
arry = source(table, column, onlyAvail);
|
1053
|
-
} else if ($.type(source) === 'object' &&
|
1089
|
+
} else if ($.type(source) === 'object' && fxn) {
|
1054
1090
|
// custom select source function for a SPECIFIC COLUMN
|
1055
|
-
arry =
|
1091
|
+
arry = fxn(table, column, onlyAvail);
|
1056
1092
|
}
|
1057
1093
|
if (arry === false) {
|
1058
1094
|
// fall back to original method
|
@@ -1159,6 +1195,8 @@ ts.filter = {
|
|
1159
1195
|
$filters = $filters && $filters.length ? $filters.add(wo.filter_$externalFilters) : wo.filter_$externalFilters;
|
1160
1196
|
}
|
1161
1197
|
$filters.filter('select[data-column="' + column + '"]')[ updating ? 'html' : 'append' ](options);
|
1198
|
+
if (!wo.filter_functions) { wo.filter_functions = {}; }
|
1199
|
+
wo.filter_functions[column] = true;
|
1162
1200
|
},
|
1163
1201
|
buildDefault: function(table, updating) {
|
1164
1202
|
var columnIndex, $header,
|
@@ -1169,10 +1207,7 @@ ts.filter = {
|
|
1169
1207
|
for (columnIndex = 0; columnIndex < columns; columnIndex++) {
|
1170
1208
|
$header = c.$headers.filter('[data-column="' + columnIndex + '"]:last');
|
1171
1209
|
// look for the filter-select class; build/update it if found
|
1172
|
-
if (($header.hasClass('filter-select') ||
|
1173
|
-
!$header.hasClass('filter-false')) {
|
1174
|
-
if (!wo.filter_functions) { wo.filter_functions = {}; }
|
1175
|
-
wo.filter_functions[columnIndex] = true; // make sure this select gets processed by filter_functions
|
1210
|
+
if (($header.hasClass('filter-select') || ts.getColumnData( table, wo.filter_functions, columnIndex ) === true) && !$header.hasClass('filter-false')) {
|
1176
1211
|
ts.filter.buildSelect(table, columnIndex, updating, $header.hasClass(wo.filter_onlyAvail));
|
1177
1212
|
}
|
1178
1213
|
}
|
@@ -1244,6 +1279,7 @@ ts.setFilters = function(table, filter, apply, skipFirst) {
|
|
1244
1279
|
if (c && apply) {
|
1245
1280
|
// ensure new set filters are applied, even if the search is the same
|
1246
1281
|
c.lastCombinedFilter = null;
|
1282
|
+
c.lastSearch = [];
|
1247
1283
|
ts.filter.searching(c.$table[0], filter, skipFirst);
|
1248
1284
|
c.$table.trigger('filterFomatterUpdate');
|
1249
1285
|
}
|
@@ -1475,7 +1511,7 @@ ts.addWidget({
|
|
1475
1511
|
var canResize,
|
1476
1512
|
$column = $(this);
|
1477
1513
|
column = $column.attr('data-column');
|
1478
|
-
canResize = ts.getData( $column, c.headers
|
1514
|
+
canResize = ts.getData( $column, ts.getColumnData( table, c.headers, column ), 'resizable') === "false";
|
1479
1515
|
$rows.children().filter('[data-column="' + column + '"]')[canResize ? 'addClass' : 'removeClass']('resizable-false');
|
1480
1516
|
});
|
1481
1517
|
// add wrapper inside each cell to allow for positioning of the resizable target block
|