jquery-tablesorter 1.12.7 → 1.12.8
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 +49 -12
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +38 -33
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +204 -130
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-duration.js +40 -0
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-ignore-articles.js +23 -9
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +9 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +113 -26
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +21 -10
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f537540ad9cb3ae7519f0ede00b10a967df49b5
|
4
|
+
data.tar.gz: 4e043ff89f30abfa0bb964799a352dbe63d61b81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1ee4421ddd5364f2f8471cdfa0ca6c1a9ef3794f53721092a859236b7492e756c3a925a7e9d4e6c5bc2725d2d8ba29be917ff82c9bb85972c218090ad54bf1a
|
7
|
+
data.tar.gz: c71c7fd64e88115f2a3fb66a3205c050001c4da2cfed4cf0a1178a4a18932d2ede7d40cc0b43b2ae25cfa3d1ad9e21bc32880acf0ceb5f001d2887817d54a4f3
|
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.17.
|
7
|
+
Current tablesorter version: 2.17.8 (9/15/2014), [documentation]
|
8
8
|
|
9
9
|
Any issue associated with the js/css files, please report to [Mottie's fork].
|
10
10
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
* tablesorter pager plugin
|
3
|
-
* updated
|
3
|
+
* updated 9/15/2014 (v2.17.8)
|
4
4
|
*/
|
5
5
|
/*jshint browser:true, jquery:true, unused:false */
|
6
6
|
;(function($) {
|
@@ -58,13 +58,16 @@
|
|
58
58
|
// starting page of the pager (zero based index)
|
59
59
|
page: 0,
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
// reset pager after filtering; set to desired page #
|
62
|
+
// set to false to not change page at filter start
|
63
63
|
pageReset: 0,
|
64
64
|
|
65
65
|
// Number of visible rows
|
66
66
|
size: 10,
|
67
67
|
|
68
|
+
// Number of options to include in the pager number selector
|
69
|
+
maxOptionSize: 20,
|
70
|
+
|
68
71
|
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
|
69
72
|
savePages: true,
|
70
73
|
|
@@ -186,10 +189,37 @@
|
|
186
189
|
if ( p.$goto.length ) {
|
187
190
|
t = '';
|
188
191
|
pg = Math.min( p.totalPages, p.filteredPages );
|
189
|
-
|
190
|
-
|
192
|
+
// Filter the options page number link array if it's larger than 'maxOptionSize'
|
193
|
+
// as large page set links will slow the browser on large dom inserts
|
194
|
+
var skip_set_size = Math.floor(pg / p.maxOptionSize),
|
195
|
+
large_collection = pg > p.maxOptionSize,
|
196
|
+
current_page = p.page + 1,
|
197
|
+
start_page = 1,
|
198
|
+
end_page = pg,
|
199
|
+
option_pages = [];
|
200
|
+
//construct default options pages array
|
201
|
+
var option_pages_start_page = (large_collection && current_page == 1) ? skip_set_size : 1;
|
202
|
+
for (i = option_pages_start_page; i <= pg;) {
|
203
|
+
option_pages.push(i);
|
204
|
+
i = large_collection ? i + skip_set_size : i++;
|
205
|
+
}
|
206
|
+
if (large_collection) {
|
207
|
+
var central_focus_size = Math.floor(p.maxOptionSize / 2) - 1,
|
208
|
+
lower_focus_window = Math.abs(Math.floor(current_page - central_focus_size/2)),
|
209
|
+
focus_option_pages = [];
|
210
|
+
start_page = Math.min(current_page, lower_focus_window);
|
211
|
+
end_page = start_page + central_focus_size;
|
212
|
+
//construct an array to get a focus set around the current page
|
213
|
+
for (i = start_page; i <= end_page ; i++) focus_option_pages.push(i);
|
214
|
+
var insert_index = Math.floor(option_pages.length / 2) - Math.floor(focus_option_pages.length / 2);
|
215
|
+
Array.prototype.splice.apply(option_pages, [ insert_index, focus_option_pages.length ].concat(focus_option_pages));
|
216
|
+
option_pages.sort(function sortNumber(a,b) { return a - b; });
|
217
|
+
}
|
218
|
+
for ( i = 0; i < option_pages.length; i++) {
|
219
|
+
t += '<option>' + option_pages[i] + '</option>';
|
191
220
|
}
|
192
|
-
p.$goto.
|
221
|
+
p.$goto[0].innerHTML = t;
|
222
|
+
p.$goto[0].value = current_page;
|
193
223
|
}
|
194
224
|
// rebind startRow/page inputs
|
195
225
|
$out.find('.ts-startRow, .ts-page').unbind('change').bind('change', function(){
|
@@ -532,9 +562,8 @@
|
|
532
562
|
}
|
533
563
|
updatePageDisplay(table, p);
|
534
564
|
if ( !p.isDisabled ) { fixHeight(table, p); }
|
535
|
-
$t.trigger('applyWidgets');
|
536
565
|
if (table.isUpdating) {
|
537
|
-
$t.trigger(
|
566
|
+
$t.trigger('updateComplete', [ table, true ]);
|
538
567
|
}
|
539
568
|
},
|
540
569
|
|
@@ -553,6 +582,7 @@
|
|
553
582
|
.removeAttr('aria-describedby')
|
554
583
|
.find('tr.pagerSavedHeightSpacer').remove();
|
555
584
|
renderTable(table, table.config.rowsCopy, p);
|
585
|
+
$(table).trigger('applyWidgets');
|
556
586
|
if (table.config.debug) {
|
557
587
|
ts.log('pager disabled');
|
558
588
|
}
|
@@ -621,7 +651,7 @@
|
|
621
651
|
.trigger('pageMoved', p)
|
622
652
|
.trigger('applyWidgets');
|
623
653
|
if (table.isUpdating) {
|
624
|
-
$t.trigger('updateComplete');
|
654
|
+
$t.trigger('updateComplete', [ table, true ]);
|
625
655
|
}
|
626
656
|
}
|
627
657
|
},
|
@@ -751,7 +781,7 @@
|
|
751
781
|
p.regexRows = new RegExp('(' + (wo.filter_filteredRow || 'filtered') + '|' + c.selectorRemove.replace(/^(\w+\.)/g,'') + '|' + c.cssChildRow + ')');
|
752
782
|
|
753
783
|
$t
|
754
|
-
.unbind('filterStart filterEnd sortEnd disable enable destroy
|
784
|
+
.unbind('filterStart filterEnd sortEnd disable enable destroy updateComplete pageSize '.split(' ').join('.pager '))
|
755
785
|
.bind('filterStart.pager', function(e, filters) {
|
756
786
|
p.currentFilters = filters;
|
757
787
|
// don't change page is filters are the same (pager updating, etc)
|
@@ -769,6 +799,7 @@
|
|
769
799
|
// update page display first, so we update p.filteredPages
|
770
800
|
updatePageDisplay(table, p, false);
|
771
801
|
moveToPage(table, p, false);
|
802
|
+
c.$table.trigger('applyWidgets');
|
772
803
|
fixHeight(table, p);
|
773
804
|
}
|
774
805
|
})
|
@@ -784,12 +815,18 @@
|
|
784
815
|
e.stopPropagation();
|
785
816
|
destroyPager(table, p);
|
786
817
|
})
|
787
|
-
.bind('
|
818
|
+
.bind('updateComplete.pager', function(e, table, triggered){
|
788
819
|
e.stopPropagation();
|
820
|
+
// table can be unintentionally undefined in tablesorter v2.17.7 and earlier
|
821
|
+
if ( !table || triggered ) { return; }
|
789
822
|
fixHeight(table, p);
|
790
|
-
var $rows = c.$tbodies.eq(0).children('tr');
|
823
|
+
var $rows = c.$tbodies.eq(0).children('tr').not(c.selectorRemove);
|
791
824
|
p.totalRows = $rows.length - ( p.countChildRows ? 0 : $rows.filter('.' + c.cssChildRow).length );
|
792
825
|
p.totalPages = Math.ceil( p.totalRows / p.size );
|
826
|
+
if ($rows.length && c.rowsCopy && c.rowsCopy.length === 0) {
|
827
|
+
// make a copy of all table rows once the cache has been built
|
828
|
+
updateCache(table);
|
829
|
+
}
|
793
830
|
updatePageDisplay(table, p);
|
794
831
|
hideRows(table, p);
|
795
832
|
})
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**!
|
2
|
-
* TableSorter 2.17.
|
2
|
+
* TableSorter 2.17.8 - 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.17.
|
27
|
+
ts.version = "2.17.8";
|
28
28
|
|
29
29
|
ts.parsers = [];
|
30
30
|
ts.widgets = [];
|
@@ -246,9 +246,9 @@
|
|
246
246
|
p = ts.getParserById( ts.getData(h, ch, 'sorter') );
|
247
247
|
np = ts.getData(h, ch, 'parser') === 'false';
|
248
248
|
// empty cells behaviour - keeping emptyToBottom for backwards compatibility
|
249
|
-
c.empties[i] = ts.getData(h, ch, 'empty') || c.emptyTo || (c.emptyToBottom ? 'bottom' : 'top' );
|
249
|
+
c.empties[i] = ( ts.getData(h, ch, 'empty') || c.emptyTo || (c.emptyToBottom ? 'bottom' : 'top' ) ).toLowerCase();
|
250
250
|
// text strings behaviour in numerical sorts
|
251
|
-
c.strings[i] = ts.getData(h, ch, 'string') || c.stringTo || 'max';
|
251
|
+
c.strings[i] = ( ts.getData(h, ch, 'string') || c.stringTo || 'max' ).toLowerCase();
|
252
252
|
if (np) {
|
253
253
|
p = ts.getParserById('no-parser');
|
254
254
|
}
|
@@ -447,14 +447,16 @@
|
|
447
447
|
ch = ts.getColumnData( table, c.headers, index, true );
|
448
448
|
// save original header content
|
449
449
|
c.headerContent[index] = $(this).html();
|
450
|
-
//
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
if (
|
450
|
+
// if headerTemplate is empty, don't reformat the header cell
|
451
|
+
if ( c.headerTemplate !== '' ) {
|
452
|
+
// set up header template
|
453
|
+
t = c.headerTemplate.replace(/\{content\}/g, $(this).html()).replace(/\{icon\}/g, i);
|
454
|
+
if (c.onRenderTemplate) {
|
455
|
+
h = c.onRenderTemplate.apply($t, [index, t]);
|
456
|
+
if (h && typeof h === 'string') { t = h; } // only change t if something is returned
|
457
|
+
}
|
458
|
+
$(this).html('<div class="' + ts.css.headerIn + '">' + t + '</div>'); // faster than wrapInner
|
455
459
|
}
|
456
|
-
$(this).html('<div class="' + ts.css.headerIn + '">' + t + '</div>'); // faster than wrapInner
|
457
|
-
|
458
460
|
if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index]); }
|
459
461
|
this.column = parseInt( $(this).attr('data-column'), 10);
|
460
462
|
this.order = formatSortingOrder( ts.getData($t, ch, 'sortInitialOrder') || c.sortInitialOrder ) ? [1,0,2] : [0,1,2];
|
@@ -560,14 +562,16 @@
|
|
560
562
|
|
561
563
|
// automatically add col group, and column sizes if set
|
562
564
|
function fixColumnWidth(table) {
|
563
|
-
|
564
|
-
|
565
|
-
|
565
|
+
var colgroup, overallWidth,
|
566
|
+
c = table.config;
|
567
|
+
if (c.widthFixed && c.$table.find('colgroup').length === 0) {
|
568
|
+
colgroup = $('<colgroup>');
|
569
|
+
overallWidth = $(table).width();
|
566
570
|
// only add col for visible columns - fixes #371
|
567
|
-
$(table.tBodies
|
571
|
+
$(table.tBodies).not('.' + c.cssInfoBlock).find("tr:first").children(":visible").each(function() {
|
568
572
|
colgroup.append($('<col>').css('width', parseInt(($(this).width()/overallWidth)*1000, 10)/10 + '%'));
|
569
573
|
});
|
570
|
-
|
574
|
+
c.$table.prepend(colgroup);
|
571
575
|
}
|
572
576
|
}
|
573
577
|
|
@@ -798,7 +802,7 @@
|
|
798
802
|
function resortComplete($table, callback){
|
799
803
|
var table = $table[0];
|
800
804
|
if (table.isUpdating) {
|
801
|
-
$table.trigger('updateComplete');
|
805
|
+
$table.trigger('updateComplete', table);
|
802
806
|
}
|
803
807
|
if ($.isFunction(callback)) {
|
804
808
|
callback($table[0]);
|
@@ -1047,7 +1051,10 @@
|
|
1047
1051
|
return (version[0] > 1) || (version[0] === 1 && parseInt(version[1], 10) >= 4);
|
1048
1052
|
})($.fn.jquery.split("."));
|
1049
1053
|
// digit sort text location; keeping max+/- for backwards compatibility
|
1050
|
-
c.string = { 'max': 1, 'min': -1, '
|
1054
|
+
c.string = { 'max': 1, 'min': -1, 'emptymin': 1, 'emptymax': -1, 'zero': 0, 'none': 0, 'null': 0, 'top': true, 'bottom': false };
|
1055
|
+
// ensure case insensitivity
|
1056
|
+
c.emptyTo = c.emptyTo.toLowerCase();
|
1057
|
+
c.stringTo = c.stringTo.toLowerCase();
|
1051
1058
|
// add table theme class only if there isn't already one there
|
1052
1059
|
if (!/tablesorter\-/.test($table.attr('class'))) {
|
1053
1060
|
k = (c.theme !== '' ? ' tablesorter-' + c.theme : '');
|
@@ -1761,6 +1768,7 @@
|
|
1761
1768
|
format: function(s) {
|
1762
1769
|
return s ? $.trim(s.replace(/(https?|ftp|file):\/\//, '')) : s;
|
1763
1770
|
},
|
1771
|
+
parsed : true, // filter widget flag
|
1764
1772
|
type: "text"
|
1765
1773
|
});
|
1766
1774
|
|
@@ -1853,7 +1861,7 @@
|
|
1853
1861
|
id: "zebra",
|
1854
1862
|
priority: 90,
|
1855
1863
|
format: function(table, c, wo) {
|
1856
|
-
var $tb, $tv, $tr, row, even, time, k,
|
1864
|
+
var $tb, $tv, $tr, row, even, time, k,
|
1857
1865
|
child = new RegExp(c.cssChildRow, 'i'),
|
1858
1866
|
b = c.$tbodies;
|
1859
1867
|
if (c.debug) {
|
@@ -1861,21 +1869,18 @@
|
|
1861
1869
|
}
|
1862
1870
|
for (k = 0; k < b.length; k++ ) {
|
1863
1871
|
// loop through the visible rows
|
1872
|
+
row = 0;
|
1864
1873
|
$tb = b.eq(k);
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
even = (row % 2 === 0);
|
1876
|
-
$tr.removeClass(wo.zebra[even ? 1 : 0]).addClass(wo.zebra[even ? 0 : 1]);
|
1877
|
-
});
|
1878
|
-
}
|
1874
|
+
$tv = $tb.children('tr:visible').not(c.selectorRemove);
|
1875
|
+
// revered back to using jQuery each - strangely it's the fastest method
|
1876
|
+
/*jshint loopfunc:true */
|
1877
|
+
$tv.each(function(){
|
1878
|
+
$tr = $(this);
|
1879
|
+
// style child rows the same way the parent row was styled
|
1880
|
+
if (!child.test(this.className)) { row++; }
|
1881
|
+
even = (row % 2 === 0);
|
1882
|
+
$tr.removeClass(wo.zebra[even ? 1 : 0]).addClass(wo.zebra[even ? 0 : 1]);
|
1883
|
+
});
|
1879
1884
|
}
|
1880
1885
|
if (c.debug) {
|
1881
1886
|
ts.benchmark("Applying Zebra widget", time);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! tableSorter 2.16+ widgets - updated
|
1
|
+
/*! tableSorter 2.16+ widgets - updated 9/15/2014 (v2.17.8)
|
2
2
|
*
|
3
3
|
* Column Styles
|
4
4
|
* Column Filters
|
@@ -245,7 +245,7 @@ ts.addWidget({
|
|
245
245
|
ts.benchmark("Applying " + theme + " theme", time);
|
246
246
|
}
|
247
247
|
},
|
248
|
-
remove: function(table, c
|
248
|
+
remove: function(table, c) {
|
249
249
|
var $table = c.$table,
|
250
250
|
theme = c.theme || 'jui',
|
251
251
|
themes = ts.themes[ theme ] || ts.themes.jui,
|
@@ -354,6 +354,8 @@ ts.addWidget({
|
|
354
354
|
filter_childRows : false, // if true, filter includes child row content in the search
|
355
355
|
filter_columnFilters : true, // if true, a filter will be added to the top of each table column
|
356
356
|
filter_cssFilter : '', // css class name added to the filter row & each input in the row (tablesorter-filter is ALWAYS added)
|
357
|
+
filter_defaultFilter : {}, // add a default column filter type "~{query}" to make fuzzy searches default; "{q1} AND {q2}" to make all searches use a logical AND.
|
358
|
+
filter_excludeFilter : {}, // filters to exclude, per column
|
357
359
|
filter_external : '', // jQuery selector string (or jQuery object) of external filters
|
358
360
|
filter_filteredRow : 'filtered', // class added to filtered rows; needed by pager plugin
|
359
361
|
filter_formatter : null, // add custom filter elements to the filter row
|
@@ -410,24 +412,25 @@ ts.filter = {
|
|
410
412
|
type : /undefined|number/, // check type
|
411
413
|
exact : /(^[\"|\'|=]+)|([\"|\'|=]+$)/g, // exact match (allow '==')
|
412
414
|
nondigit : /[^\w,. \-()]/g, // replace non-digits (from digit & currency parser)
|
413
|
-
operators : /[<>=]/g // replace operators
|
415
|
+
operators : /[<>=]/g, // replace operators
|
416
|
+
query : '(q|query)' // replace filter queries
|
414
417
|
},
|
415
|
-
// function(
|
416
|
-
//
|
417
|
-
//
|
418
|
-
//
|
419
|
-
//
|
420
|
-
//
|
421
|
-
//
|
422
|
-
// parsed = array (by column) of boolean values (from filter_useParsedData or "filter-parsed" class)
|
418
|
+
// function( c, data ) { }
|
419
|
+
// c = table.config
|
420
|
+
// data.filter = array of filter input values; data.iFilter = same array, except lowercase
|
421
|
+
// data.exact = table cell text (or parsed data if column parser enabled)
|
422
|
+
// data.iExact = same as data.exact, except lowercase
|
423
|
+
// data.cache = table cell text from cache, so it has been parsed
|
424
|
+
// data.index = column index; table = table element (DOM)
|
425
|
+
// data.parsed = array (by column) of boolean values (from filter_useParsedData or "filter-parsed" class)
|
423
426
|
types: {
|
424
427
|
// Look for regex
|
425
|
-
regex: function(
|
426
|
-
if ( ts.filter.regex.regex.test(iFilter) ) {
|
428
|
+
regex: function( c, data ) {
|
429
|
+
if ( ts.filter.regex.regex.test(data.iFilter) ) {
|
427
430
|
var matches,
|
428
|
-
regex = ts.filter.regex.regex.exec(iFilter);
|
431
|
+
regex = ts.filter.regex.regex.exec(data.iFilter);
|
429
432
|
try {
|
430
|
-
matches = new RegExp(regex[1], regex[2]).test( iExact );
|
433
|
+
matches = new RegExp(regex[1], regex[2]).test( data.iExact );
|
431
434
|
} catch (error) {
|
432
435
|
matches = false;
|
433
436
|
}
|
@@ -436,27 +439,29 @@ ts.filter = {
|
|
436
439
|
return null;
|
437
440
|
},
|
438
441
|
// Look for operators >, >=, < or <=
|
439
|
-
operators: function(
|
440
|
-
if ( /^[<>]=?/.test(iFilter) ) {
|
442
|
+
operators: function( c, data ) {
|
443
|
+
if ( /^[<>]=?/.test(data.iFilter) ) {
|
441
444
|
var cachedValue, result,
|
442
|
-
|
443
|
-
|
445
|
+
table = c.table,
|
446
|
+
index = data.index,
|
447
|
+
parsed = data.parsed[index],
|
448
|
+
query = ts.formatFloat( data.iFilter.replace(ts.filter.regex.operators, ''), table ),
|
444
449
|
parser = c.parsers[index],
|
445
450
|
savedSearch = query;
|
446
451
|
// parse filter value in case we're comparing numbers (dates)
|
447
|
-
if (parsed
|
448
|
-
result = ts.filter.parseFilter(
|
452
|
+
if (parsed || parser.type === 'numeric') {
|
453
|
+
result = ts.filter.parseFilter(c, $.trim('' + data.iFilter.replace(ts.filter.regex.operators, '')), index, parsed, true);
|
449
454
|
query = ( typeof result === "number" && result !== '' && !isNaN(result) ) ? result : query;
|
450
455
|
}
|
451
456
|
|
452
457
|
// iExact may be numeric - see issue #149;
|
453
458
|
// check if cached is defined, because sometimes j goes out of range? (numeric columns)
|
454
|
-
cachedValue = ( parsed
|
455
|
-
isNaN(iExact) ? ts.formatFloat( iExact.replace(ts.filter.regex.nondigit, ''), table) :
|
456
|
-
ts.formatFloat( iExact, table );
|
459
|
+
cachedValue = ( parsed || parser.type === 'numeric' ) && !isNaN(query) && typeof data.cache !== 'undefined' ? data.cache :
|
460
|
+
isNaN(data.iExact) ? ts.formatFloat( data.iExact.replace(ts.filter.regex.nondigit, ''), table) :
|
461
|
+
ts.formatFloat( data.iExact, table );
|
457
462
|
|
458
|
-
if ( />/.test(iFilter) ) { result = />=/.test(iFilter) ? cachedValue >= query : cachedValue > query; }
|
459
|
-
if ( /</.test(iFilter) ) { result = /<=/.test(iFilter) ? cachedValue <= query : cachedValue < query; }
|
463
|
+
if ( />/.test(data.iFilter) ) { result = />=/.test(data.iFilter) ? cachedValue >= query : cachedValue > query; }
|
464
|
+
if ( /</.test(data.iFilter) ) { result = /<=/.test(data.iFilter) ? cachedValue <= query : cachedValue < query; }
|
460
465
|
// keep showing all rows if nothing follows the operator
|
461
466
|
if ( !result && savedSearch === '' ) { result = true; }
|
462
467
|
return result;
|
@@ -464,37 +469,40 @@ ts.filter = {
|
|
464
469
|
return null;
|
465
470
|
},
|
466
471
|
// Look for a not match
|
467
|
-
notMatch: function(
|
468
|
-
if ( /^\!/.test(iFilter) ) {
|
469
|
-
|
470
|
-
|
472
|
+
notMatch: function( c, data ) {
|
473
|
+
if ( /^\!/.test(data.iFilter) ) {
|
474
|
+
var indx,
|
475
|
+
filter = ts.filter.parseFilter(c, data.iFilter.replace('!', ''), data.index, data.parsed[data.index]);
|
476
|
+
if (ts.filter.regex.exact.test(filter)) {
|
471
477
|
// look for exact not matches - see #628
|
472
|
-
|
473
|
-
return
|
478
|
+
filter = filter.replace(ts.filter.regex.exact, '');
|
479
|
+
return filter === '' ? true : $.trim(filter) !== data.iExact;
|
474
480
|
} else {
|
475
|
-
|
476
|
-
return
|
481
|
+
indx = data.iExact.search( $.trim(filter) );
|
482
|
+
return filter === '' ? true : !(c.widgetOptions.filter_startsWith ? indx === 0 : indx >= 0);
|
477
483
|
}
|
478
484
|
}
|
479
485
|
return null;
|
480
486
|
},
|
481
487
|
// Look for quotes or equals to get an exact match; ignore type since iExact could be numeric
|
482
|
-
exact: function(
|
488
|
+
exact: function( c, data ) {
|
483
489
|
/*jshint eqeqeq:false */
|
484
|
-
if (ts.filter.regex.exact.test(iFilter)) {
|
485
|
-
var
|
486
|
-
return
|
490
|
+
if (ts.filter.regex.exact.test(data.iFilter)) {
|
491
|
+
var filter = ts.filter.parseFilter(c, data.iFilter.replace(ts.filter.regex.exact, ''), data.index, data.parsed[data.index]);
|
492
|
+
return data.anyMatch ? $.inArray(filter, data.rowArray) >= 0 : filter == data.iExact;
|
487
493
|
}
|
488
494
|
return null;
|
489
495
|
},
|
490
496
|
// Look for an AND or && operator (logical and)
|
491
|
-
and : function(
|
492
|
-
if ( ts.filter.regex.andTest.test(filter) ) {
|
493
|
-
var
|
494
|
-
|
497
|
+
and : function( c, data ) {
|
498
|
+
if ( ts.filter.regex.andTest.test(data.filter) ) {
|
499
|
+
var index = data.index,
|
500
|
+
parsed = data.parsed[index],
|
501
|
+
query = data.iFilter.split( ts.filter.regex.andSplit ),
|
502
|
+
result = data.iExact.search( $.trim( ts.filter.parseFilter(c, query[0], index, parsed) ) ) >= 0,
|
495
503
|
indx = query.length - 1;
|
496
504
|
while (result && indx) {
|
497
|
-
result = result && iExact.search( $.trim(ts.filter.parseFilter(
|
505
|
+
result = result && data.iExact.search( $.trim( ts.filter.parseFilter(c, query[indx], index, parsed) ) ) >= 0;
|
498
506
|
indx--;
|
499
507
|
}
|
500
508
|
return result;
|
@@ -502,52 +510,55 @@ ts.filter = {
|
|
502
510
|
return null;
|
503
511
|
},
|
504
512
|
// Look for a range (using " to " or " - ") - see issue #166; thanks matzhu!
|
505
|
-
range : function(
|
506
|
-
if ( ts.filter.regex.toTest.test(iFilter) ) {
|
513
|
+
range : function( c, data ) {
|
514
|
+
if ( ts.filter.regex.toTest.test(data.iFilter) ) {
|
507
515
|
var result, tmp,
|
508
|
-
|
516
|
+
table = c.table,
|
517
|
+
index = data.index,
|
518
|
+
parsed = data.parsed[index],
|
509
519
|
// make sure the dash is for a range and not indicating a negative number
|
510
|
-
query = iFilter.split( ts.filter.regex.toSplit ),
|
511
|
-
range1 = ts.formatFloat( ts.filter.parseFilter(
|
512
|
-
range2 = ts.formatFloat( ts.filter.parseFilter(
|
520
|
+
query = data.iFilter.split( ts.filter.regex.toSplit ),
|
521
|
+
range1 = ts.formatFloat( ts.filter.parseFilter(c, query[0].replace(ts.filter.regex.nondigit, ''), index, parsed), table ),
|
522
|
+
range2 = ts.formatFloat( ts.filter.parseFilter(c, query[1].replace(ts.filter.regex.nondigit, ''), index, parsed), table );
|
513
523
|
// parse filter value in case we're comparing numbers (dates)
|
514
|
-
if (parsed
|
524
|
+
if (parsed || c.parsers[index].type === 'numeric') {
|
515
525
|
result = c.parsers[index].format('' + query[0], table, c.$headers.eq(index), index);
|
516
526
|
range1 = (result !== '' && !isNaN(result)) ? result : range1;
|
517
527
|
result = c.parsers[index].format('' + query[1], table, c.$headers.eq(index), index);
|
518
528
|
range2 = (result !== '' && !isNaN(result)) ? result : range2;
|
519
529
|
}
|
520
|
-
result = ( parsed
|
521
|
-
isNaN(iExact) ? ts.formatFloat( iExact.replace(ts.filter.regex.nondigit, ''), table) :
|
522
|
-
ts.formatFloat( iExact, table );
|
530
|
+
result = ( parsed || c.parsers[index].type === 'numeric' ) && !isNaN(range1) && !isNaN(range2) ? data.cache :
|
531
|
+
isNaN(data.iExact) ? ts.formatFloat( data.iExact.replace(ts.filter.regex.nondigit, ''), table) :
|
532
|
+
ts.formatFloat( data.iExact, table );
|
523
533
|
if (range1 > range2) { tmp = range1; range1 = range2; range2 = tmp; } // swap
|
524
534
|
return (result >= range1 && result <= range2) || (range1 === '' || range2 === '');
|
525
535
|
}
|
526
536
|
return null;
|
527
537
|
},
|
528
538
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
529
|
-
wild : function(
|
530
|
-
if ( /[\?|\*]/.test(iFilter) || ts.filter.regex.orReplace.test(filter) ) {
|
531
|
-
var
|
532
|
-
|
539
|
+
wild : function( c, data ) {
|
540
|
+
if ( /[\?|\*]/.test(data.iFilter) || ts.filter.regex.orReplace.test(data.filter) ) {
|
541
|
+
var index = data.index,
|
542
|
+
parsed = data.parsed[index],
|
543
|
+
query = ts.filter.parseFilter(c, data.iFilter.replace(ts.filter.regex.orReplace, "|"), index, parsed);
|
533
544
|
// look for an exact match with the "or" unless the "filter-match" class is found
|
534
545
|
if (!c.$headers.filter('[data-column="' + index + '"]:last').hasClass('filter-match') && /\|/.test(query)) {
|
535
|
-
query = $.isArray(rowArray) ? '(' + query + ')' : '^(' + query + ')$';
|
546
|
+
query = data.anyMatch && $.isArray(data.rowArray) ? '(' + query + ')' : '^(' + query + ')$';
|
536
547
|
}
|
537
548
|
// parsing the filter may not work properly when using wildcards =/
|
538
|
-
return new RegExp( query.replace(/\?/g, '\\S{1}').replace(/\*/g, '\\S*') ).test(iExact);
|
549
|
+
return new RegExp( query.replace(/\?/g, '\\S{1}').replace(/\*/g, '\\S*') ).test(data.iExact);
|
539
550
|
}
|
540
551
|
return null;
|
541
552
|
},
|
542
553
|
// fuzzy text search; modified from https://github.com/mattyork/fuzzy (MIT license)
|
543
|
-
fuzzy: function(
|
544
|
-
if ( /^~/.test(iFilter) ) {
|
554
|
+
fuzzy: function( c, data ) {
|
555
|
+
if ( /^~/.test(data.iFilter) ) {
|
545
556
|
var indx,
|
546
557
|
patternIndx = 0,
|
547
|
-
len = iExact.length,
|
548
|
-
pattern = ts.filter.parseFilter(
|
558
|
+
len = data.iExact.length,
|
559
|
+
pattern = ts.filter.parseFilter(c, data.iFilter.slice(1), data.index, data.parsed[data.index]);
|
549
560
|
for (indx = 0; indx < len; indx++) {
|
550
|
-
if (iExact[indx] === pattern[patternIndx]) {
|
561
|
+
if (data.iExact[indx] === pattern[patternIndx]) {
|
551
562
|
patternIndx += 1;
|
552
563
|
}
|
553
564
|
}
|
@@ -579,7 +590,9 @@ ts.filter = {
|
|
579
590
|
wo.filter_initTimer = null;
|
580
591
|
wo.filter_formatterCount = 0;
|
581
592
|
wo.filter_formatterInit = [];
|
593
|
+
wo.filter_initializing = true;
|
582
594
|
|
595
|
+
txt = '\\{' + ts.filter.regex.query + '\\}';
|
583
596
|
$.extend( regex, {
|
584
597
|
child : new RegExp(c.cssChildRow),
|
585
598
|
filtered : new RegExp(wo.filter_filteredRow),
|
@@ -588,7 +601,9 @@ ts.filter = {
|
|
588
601
|
toSplit : new RegExp('(?:\\s+(?:-|' + ts.language.to + ')\\s+)' ,'gi'),
|
589
602
|
andTest : new RegExp('\\s+(' + ts.language.and + '|&&)\\s+', 'i'),
|
590
603
|
andSplit : new RegExp('(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi'),
|
591
|
-
orReplace : new RegExp('\\s+(' + ts.language.or + ')\\s+', 'gi')
|
604
|
+
orReplace : new RegExp('\\s+(' + ts.language.or + ')\\s+', 'gi'),
|
605
|
+
iQuery : new RegExp(txt, 'i'),
|
606
|
+
igQuery : new RegExp(txt, 'ig')
|
592
607
|
});
|
593
608
|
|
594
609
|
// don't build filter row if columnFilters is false or all columns are set to "filter-false" - issue #156
|
@@ -741,7 +756,13 @@ ts.filter = {
|
|
741
756
|
},
|
742
757
|
filterInitComplete: function(c){
|
743
758
|
var wo = c.widgetOptions,
|
744
|
-
count = 0
|
759
|
+
count = 0,
|
760
|
+
completed = function(){
|
761
|
+
wo.filter_initialized = true;
|
762
|
+
wo.filter_initializing = false;
|
763
|
+
ts.filter.findRows(c.table, c.$table.data('lastSearch'), null);
|
764
|
+
c.$table.trigger('filterInit', c);
|
765
|
+
};
|
745
766
|
$.each( wo.filter_formatterInit, function(i, val) {
|
746
767
|
if (val === 1) {
|
747
768
|
count++;
|
@@ -750,17 +771,16 @@ ts.filter = {
|
|
750
771
|
clearTimeout(wo.filter_initTimer);
|
751
772
|
if (!wo.filter_initialized && count === wo.filter_formatterCount) {
|
752
773
|
// filter widget initialized
|
753
|
-
|
754
|
-
c.$table.trigger('filterInit', c);
|
774
|
+
completed();
|
755
775
|
} else if (!wo.filter_initialized) {
|
756
776
|
// fall back in case a filter_formatter doesn't call
|
757
777
|
// $.tablesorter.filter.formatterUpdated($cell, column), and the count is off
|
758
778
|
wo.filter_initTimer = setTimeout(function(){
|
759
|
-
|
760
|
-
c.$table.trigger('filterInit', c);
|
779
|
+
completed();
|
761
780
|
}, 500);
|
762
781
|
}
|
763
782
|
},
|
783
|
+
|
764
784
|
setDefaults: function(table, c, wo) {
|
765
785
|
var isArray, saved, indx,
|
766
786
|
// get current (default) filters
|
@@ -780,10 +800,9 @@ ts.filter = {
|
|
780
800
|
c.$table.data('lastSearch', filters);
|
781
801
|
return filters;
|
782
802
|
},
|
783
|
-
parseFilter: function(
|
784
|
-
var c = table.config;
|
803
|
+
parseFilter: function(c, filter, column, parsed, forceParse){
|
785
804
|
return forceParse || parsed ?
|
786
|
-
c.parsers[column].format( filter, table, [], column ) :
|
805
|
+
c.parsers[column].format( filter, c.table, [], column ) :
|
787
806
|
filter;
|
788
807
|
},
|
789
808
|
buildRow: function(table, c, wo) {
|
@@ -991,26 +1010,51 @@ ts.filter = {
|
|
991
1010
|
}, 200);
|
992
1011
|
});
|
993
1012
|
},
|
1013
|
+
defaultFilter: function(filter, mask){
|
1014
|
+
if (filter === '') { return filter; }
|
1015
|
+
var regex = ts.filter.regex.iQuery,
|
1016
|
+
maskLen = mask.match( ts.filter.regex.igQuery ).length,
|
1017
|
+
query = maskLen > 1 ? $.trim(filter).split(/\s/) : [ $.trim(filter) ],
|
1018
|
+
len = query.length - 1,
|
1019
|
+
indx = 0,
|
1020
|
+
val = mask;
|
1021
|
+
if ( len < 1 && maskLen > 1 ) {
|
1022
|
+
// only one "word" in query but mask has >1 slots
|
1023
|
+
query[1] = query[0];
|
1024
|
+
}
|
1025
|
+
// replace all {query} with query words...
|
1026
|
+
// if query = "Bob", then convert mask from "!{query}" to "!Bob"
|
1027
|
+
// if query = "Bob Joe Frank", then convert mask "{q} OR {q}" to "Bob OR Joe OR Frank"
|
1028
|
+
while (regex.test(val)) {
|
1029
|
+
val = val.replace(regex, query[indx++] || '');
|
1030
|
+
if (regex.test(val) && indx < len && (query[indx] || '') !== '') {
|
1031
|
+
val = mask.replace(regex, val);
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
return val;
|
1035
|
+
},
|
994
1036
|
findRows: function(table, filters, combinedFilters) {
|
995
|
-
if (table.config.lastCombinedFilter === combinedFilters) { return; }
|
996
|
-
var
|
997
|
-
childRow,
|
998
|
-
notFiltered, searchFiltered, filterMatched,
|
999
|
-
anyMatch, iAnyMatch, rowArray, rowText, iRowText, rowCache, fxn, ffxn,
|
1037
|
+
if (table.config.lastCombinedFilter === combinedFilters || table.config.widgetOptions.filter_initializing) { return; }
|
1038
|
+
var len, $rows, rowIndex, tbodyIndex, $tbody, $cells, $cell, columnIndex,
|
1039
|
+
childRow, lastSearch, hasSelect, matches, result, showRow, time, val, indx,
|
1040
|
+
notFiltered, searchFiltered, filterMatched, excludeMatch, fxn, ffxn,
|
1000
1041
|
regex = ts.filter.regex,
|
1001
1042
|
c = table.config,
|
1002
1043
|
wo = c.widgetOptions,
|
1003
|
-
columns = c.columns,
|
1004
1044
|
$tbodies = c.$table.children('tbody'), // target all tbodies #568
|
1045
|
+
// data object passed to filters; anyMatch is a flag for the filters
|
1046
|
+
data = { anyMatch: false },
|
1005
1047
|
// anyMatch really screws up with these types of filters
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1048
|
+
noAnyMatch = [ 'range', 'notMatch', 'operators' ];
|
1049
|
+
|
1050
|
+
// parse columns after formatter, in case the class is added at that point
|
1051
|
+
data.parsed = c.$headers.map(function(columnIndex) {
|
1052
|
+
return c.parsers && c.parsers[columnIndex] && c.parsers[columnIndex].parsed ||
|
1053
|
+
// getData won't return "parsed" if other "filter-" class names exist (e.g. <th class="filter-select filter-parsed">)
|
1054
|
+
ts.getData && ts.getData(c.$headers.filter('[data-column="' + columnIndex + '"]:last'), ts.getColumnData( table, c.headers, columnIndex ), 'filter') === 'parsed' ||
|
1055
|
+
$(this).hasClass('filter-parsed');
|
1056
|
+
}).get();
|
1057
|
+
|
1014
1058
|
if (c.debug) { time = new Date(); }
|
1015
1059
|
// filtered rows count
|
1016
1060
|
c.filteredRows = 0;
|
@@ -1060,15 +1104,25 @@ ts.filter = {
|
|
1060
1104
|
ts.log( "Searching through " + ( searchFiltered && notFiltered < len ? notFiltered : "all" ) + " rows" );
|
1061
1105
|
}
|
1062
1106
|
if ((wo.filter_$anyMatch && wo.filter_$anyMatch.length) || filters[c.columns]) {
|
1063
|
-
|
1107
|
+
data.anyMatchFlag = true;
|
1108
|
+
data.anyMatchFilter = wo.filter_$anyMatch && wo.filter_$anyMatch.val() || filters[c.columns] || '';
|
1064
1109
|
if (c.sortLocaleCompare) {
|
1065
1110
|
// replace accents
|
1066
|
-
|
1111
|
+
data.anyMatchFilter = ts.replaceAccents(data.anyMatchFilter);
|
1067
1112
|
}
|
1068
|
-
|
1113
|
+
if (wo.filter_defaultFilter && regex.iQuery.test( ts.getColumnData( table, wo.filter_defaultFilter, c.columns, true ) || '')) {
|
1114
|
+
data.anyMatchFilter = ts.filter.defaultFilter( data.anyMatchFilter, ts.getColumnData( table, wo.filter_defaultFilter, c.columns, true ) );
|
1115
|
+
// clear search filtered flag because default filters are not saved to the last search
|
1116
|
+
searchFiltered = false;
|
1117
|
+
}
|
1118
|
+
data.iAnyMatchFilter = data.anyMatchFilter;
|
1069
1119
|
}
|
1120
|
+
|
1070
1121
|
// loop through the rows
|
1071
1122
|
for (rowIndex = 0; rowIndex < len; rowIndex++) {
|
1123
|
+
|
1124
|
+
data.cacheArray = c.cache[tbodyIndex].normalized[rowIndex];
|
1125
|
+
|
1072
1126
|
childRow = $rows[rowIndex].className;
|
1073
1127
|
// skip child rows & already filtered rows
|
1074
1128
|
if ( regex.child.test(childRow) || (searchFiltered && regex.filtered.test(childRow)) ) { continue; }
|
@@ -1078,15 +1132,16 @@ ts.filter = {
|
|
1078
1132
|
// so, if "table.config.widgetOptions.filter_childRows" is true and there is
|
1079
1133
|
// a match anywhere in the child row, then it will make the row visible
|
1080
1134
|
// checked here so the option can be changed dynamically
|
1081
|
-
childRowText = (childRow.length && wo.filter_childRows) ? childRow.text() : '';
|
1082
|
-
childRowText = wo.filter_ignoreCase ? childRowText.toLocaleLowerCase() : childRowText;
|
1135
|
+
data.childRowText = (childRow.length && wo.filter_childRows) ? childRow.text() : '';
|
1136
|
+
data.childRowText = wo.filter_ignoreCase ? data.childRowText.toLocaleLowerCase() : data.childRowText;
|
1083
1137
|
$cells = $rows.eq(rowIndex).children();
|
1084
1138
|
|
1085
|
-
if (
|
1086
|
-
|
1139
|
+
if (data.anyMatchFlag) {
|
1140
|
+
data.anyMatch = true;
|
1141
|
+
data.rowArray = $cells.map(function(i){
|
1087
1142
|
var txt;
|
1088
|
-
if (parsed[i]) {
|
1089
|
-
txt =
|
1143
|
+
if (data.parsed[i]) {
|
1144
|
+
txt = data.cacheArray[i];
|
1090
1145
|
} else {
|
1091
1146
|
txt = wo.filter_ignoreCase ? $(this).text().toLowerCase() : $(this).text();
|
1092
1147
|
if (c.sortLocaleCompare) {
|
@@ -1095,13 +1150,15 @@ ts.filter = {
|
|
1095
1150
|
}
|
1096
1151
|
return txt;
|
1097
1152
|
}).get();
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1153
|
+
data.filter = data.anyMatchFilter;
|
1154
|
+
data.iFilter = data.iAnyMatchFilter;
|
1155
|
+
data.exact = data.rowArray.join(' ');
|
1156
|
+
data.iExact = data.exact.toLowerCase();
|
1157
|
+
data.cache = data.cacheArray.slice(0,-1).join(' ');
|
1101
1158
|
filterMatched = null;
|
1102
1159
|
$.each(ts.filter.types, function(type, typeFunction) {
|
1103
|
-
if ($.inArray(type,
|
1104
|
-
matches = typeFunction(
|
1160
|
+
if ($.inArray(type, noAnyMatch) < 0) {
|
1161
|
+
matches = typeFunction( c, data );
|
1105
1162
|
if (matches !== null) {
|
1106
1163
|
filterMatched = matches;
|
1107
1164
|
return false;
|
@@ -1113,30 +1170,37 @@ ts.filter = {
|
|
1113
1170
|
} else {
|
1114
1171
|
if (wo.filter_startsWith) {
|
1115
1172
|
showRow = false;
|
1116
|
-
columnIndex = columns;
|
1173
|
+
columnIndex = c.columns;
|
1117
1174
|
while (!showRow && columnIndex > 0) {
|
1118
1175
|
columnIndex--;
|
1119
|
-
showRow = showRow || rowArray[columnIndex].indexOf(
|
1176
|
+
showRow = showRow || data.rowArray[columnIndex].indexOf(data.iFilter) === 0;
|
1120
1177
|
}
|
1121
1178
|
} else {
|
1122
|
-
showRow = (
|
1179
|
+
showRow = (data.iExact + data.childRowText).indexOf(data.iFilter) >= 0;
|
1123
1180
|
}
|
1124
1181
|
}
|
1182
|
+
data.anyMatch = false;
|
1125
1183
|
}
|
1126
1184
|
|
1127
|
-
for (columnIndex = 0; columnIndex < columns; columnIndex++) {
|
1185
|
+
for (columnIndex = 0; columnIndex < c.columns; columnIndex++) {
|
1186
|
+
data.filter = filters[columnIndex];
|
1187
|
+
data.index = columnIndex;
|
1188
|
+
|
1189
|
+
// filter types to exclude, per column
|
1190
|
+
excludeMatch = ( ts.getColumnData( table, wo.filter_excludeFilter, columnIndex, true ) || '' ).split(/\s+/);
|
1191
|
+
|
1128
1192
|
// ignore if filter is empty or disabled
|
1129
|
-
if (
|
1130
|
-
|
1193
|
+
if (data.filter) {
|
1194
|
+
data.cache = data.cacheArray[columnIndex];
|
1131
1195
|
// check if column data should be from the cell or from parsed data
|
1132
|
-
if (wo.filter_useParsedData || parsed[columnIndex]) {
|
1133
|
-
exact =
|
1196
|
+
if (wo.filter_useParsedData || data.parsed[columnIndex]) {
|
1197
|
+
data.exact = data.cache;
|
1134
1198
|
} else {
|
1135
1199
|
// using older or original tablesorter
|
1136
|
-
exact = $.trim($cells.eq(columnIndex).text());
|
1137
|
-
exact = c.sortLocaleCompare ? ts.replaceAccents(exact) : exact; // issue #405
|
1200
|
+
data.exact = $.trim( $cells.eq(columnIndex).text() );
|
1201
|
+
data.exact = c.sortLocaleCompare ? ts.replaceAccents(data.exact) : data.exact; // issue #405
|
1138
1202
|
}
|
1139
|
-
iExact = !regex.type.test(typeof exact) && wo.filter_ignoreCase ? exact.toLocaleLowerCase() : exact;
|
1203
|
+
data.iExact = !regex.type.test(typeof data.exact) && wo.filter_ignoreCase ? data.exact.toLocaleLowerCase() : data.exact;
|
1140
1204
|
result = showRow; // if showRow is true, show that row
|
1141
1205
|
|
1142
1206
|
// in case select filter option has a different value vs text "a - z|A through Z"
|
@@ -1144,39 +1208,49 @@ ts.filter = {
|
|
1144
1208
|
c.$filters.add(c.$externalFilters).filter('[data-column="'+ columnIndex + '"]').find('select option:selected').attr('data-function-name') || '' : '';
|
1145
1209
|
|
1146
1210
|
// replace accents - see #357
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1211
|
+
data.filter = c.sortLocaleCompare ? ts.replaceAccents(data.filter) : data.filter;
|
1212
|
+
|
1213
|
+
val = true;
|
1214
|
+
if (wo.filter_defaultFilter && regex.iQuery.test( ts.getColumnData( table, wo.filter_defaultFilter, columnIndex ) || '')) {
|
1215
|
+
data.filter = ts.filter.defaultFilter( data.filter, ts.getColumnData( table, wo.filter_defaultFilter, columnIndex ) );
|
1216
|
+
// val is used to indicate that a filter select is using a default filter; so we override the exact & partial matches
|
1217
|
+
val = false;
|
1218
|
+
}
|
1219
|
+
// data.iFilter = case insensitive, data.filter = case sensitive
|
1220
|
+
data.iFilter = wo.filter_ignoreCase ? (data.filter || '').toLocaleLowerCase() : data.filter;
|
1150
1221
|
fxn = ts.getColumnData( table, wo.filter_functions, columnIndex );
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1222
|
+
$cell = c.$headers.filter('[data-column="' + columnIndex + '"]:last');
|
1223
|
+
hasSelect = $cell.hasClass('filter-select');
|
1224
|
+
if ( fxn || ( hasSelect && val ) ) {
|
1225
|
+
if (fxn === true || hasSelect) {
|
1226
|
+
// default selector uses exact match unless "filter-match" class is found
|
1227
|
+
result = ($cell.hasClass('filter-match')) ? data.iExact.search(data.iFilter) >= 0 : data.filter === data.exact;
|
1156
1228
|
} else if (typeof fxn === 'function') {
|
1157
1229
|
// filter callback( exact cell content, parser normalized content, filter input value, column index, jQuery row object )
|
1158
|
-
result = fxn(exact,
|
1159
|
-
} else if (typeof fxn[ffxn ||
|
1230
|
+
result = fxn(data.exact, data.cache, data.filter, columnIndex, $rows.eq(rowIndex));
|
1231
|
+
} else if (typeof fxn[ffxn || data.filter] === 'function') {
|
1160
1232
|
// selector option function
|
1161
|
-
result = fxn[ffxn ||
|
1233
|
+
result = fxn[ffxn || data.filter](data.exact, data.cache, data.filter, columnIndex, $rows.eq(rowIndex));
|
1162
1234
|
}
|
1163
1235
|
} else {
|
1164
1236
|
filterMatched = null;
|
1165
1237
|
// cycle through the different filters
|
1166
1238
|
// filters return a boolean or null if nothing matches
|
1167
1239
|
$.each(ts.filter.types, function(type, typeFunction) {
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1240
|
+
if ($.inArray(type, excludeMatch) < 0) {
|
1241
|
+
matches = typeFunction( c, data );
|
1242
|
+
if (matches !== null) {
|
1243
|
+
filterMatched = matches;
|
1244
|
+
return false;
|
1245
|
+
}
|
1172
1246
|
}
|
1173
1247
|
});
|
1174
1248
|
if (filterMatched !== null) {
|
1175
1249
|
result = filterMatched;
|
1176
1250
|
// Look for match, and add child row data for matching
|
1177
1251
|
} else {
|
1178
|
-
exact = (iExact + childRowText).indexOf( ts.filter.parseFilter(
|
1179
|
-
result = ( (!wo.filter_startsWith && exact >= 0) || (wo.filter_startsWith && exact === 0) );
|
1252
|
+
data.exact = (data.iExact + data.childRowText).indexOf( ts.filter.parseFilter(c, data.iFilter, columnIndex, data.parsed[columnIndex]) );
|
1253
|
+
result = ( (!wo.filter_startsWith && data.exact >= 0) || (wo.filter_startsWith && data.exact === 0) );
|
1180
1254
|
}
|
1181
1255
|
}
|
1182
1256
|
showRow = (result) ? showRow : false;
|
@@ -1469,7 +1543,7 @@ ts.addWidget({
|
|
1469
1543
|
return;
|
1470
1544
|
}
|
1471
1545
|
var $table = c.$table,
|
1472
|
-
$attach = $(wo.stickyHeaders_attachTo),
|
1546
|
+
$attach = $(wo.stickyHeaders_attachTo || 'window'),
|
1473
1547
|
$thead = $table.children('thead:first'),
|
1474
1548
|
$win = $attach.length ? $attach : $(window),
|
1475
1549
|
$header = $thead.children('tr').not('.sticky-false').children(),
|