jquery-tablesorter 1.10.10 → 1.11.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 +1 -1
- data/lib/jquery-tablesorter/version.rb +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +47 -18
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +206 -167
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter-select2.js +134 -0
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter.js +69 -67
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +98 -51
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-date-extract.js +82 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +17 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-cssStickyHeaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +359 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +272 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +49 -18
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-reflow.js +179 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +18 -45
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +123 -0
- metadata +8 -2
@@ -0,0 +1,134 @@
|
|
1
|
+
/*! Filter widget formatter functions - updated 4/22/2014 (v2.16.1-beta)
|
2
|
+
* requires: jQuery 1.7.2+, tableSorter 2.16+, filter widget 2.16+ and select2 v3.4.6+ plugin
|
3
|
+
*/
|
4
|
+
/*jshint browser:true, jquery:true, unused:false */
|
5
|
+
/*global jQuery: false */
|
6
|
+
;(function($){
|
7
|
+
"use strict";
|
8
|
+
|
9
|
+
var ts = $.tablesorter || {};
|
10
|
+
ts.filterFormatter = ts.filterFormatter || {};
|
11
|
+
|
12
|
+
/************************\
|
13
|
+
Select2 Filter Formatter
|
14
|
+
\************************/
|
15
|
+
ts.filterFormatter.select2 = function($cell, indx, select2Def) {
|
16
|
+
var o = $.extend({
|
17
|
+
// select2 filter formatter options
|
18
|
+
cellText : '', // Text (wrapped in a label element)
|
19
|
+
match : true, // adds "filter-match" to header
|
20
|
+
// include ANY select2 options below
|
21
|
+
multiple : true,
|
22
|
+
width : '100%'
|
23
|
+
|
24
|
+
}, select2Def ),
|
25
|
+
arry, data,
|
26
|
+
c = $cell.closest('table')[0].config,
|
27
|
+
wo = c.widgetOptions,
|
28
|
+
// Add a hidden input to hold the range values
|
29
|
+
$input = $('<input class="filter" type="hidden">')
|
30
|
+
.appendTo($cell)
|
31
|
+
// hidden filter update namespace trigger by filter widget
|
32
|
+
.bind('change' + c.namespace + 'filter', function(){
|
33
|
+
var val = this.value;
|
34
|
+
val = val.replace(/[/()$]/g, '').split('|');
|
35
|
+
updateSelect2(val);
|
36
|
+
}),
|
37
|
+
$header = c.$headers.filter('[data-column="' + indx + '"]:last'),
|
38
|
+
onlyAvail = $header.hasClass(wo.filter_onlyAvail),
|
39
|
+
$shcell = [],
|
40
|
+
match = o.match ? '' : '$',
|
41
|
+
|
42
|
+
// this function updates the hidden input and adds the current values to the header cell text
|
43
|
+
updateSelect2 = function(v, notrigger) {
|
44
|
+
v = typeof v === "undefined" || v === '' ? $cell.find('.select2').select2('val') || o.value || '' : v || '';
|
45
|
+
$input
|
46
|
+
// add equal to the beginning, so we filter exact numbers
|
47
|
+
.val( $.isArray(v) && v.length ? '/(' + (v || []).join(match + '|') + match + ')/' : '' )
|
48
|
+
.trigger( notrigger ? '' : 'search' ).end()
|
49
|
+
.find('.select2').select2('val', v);
|
50
|
+
// update sticky header cell
|
51
|
+
if ($shcell.length) {
|
52
|
+
$shcell
|
53
|
+
.find('.select2').select2('val', v);
|
54
|
+
}
|
55
|
+
},
|
56
|
+
|
57
|
+
// get options from table cell content or filter_selectSource (v2.16)
|
58
|
+
updateOptions = function(){
|
59
|
+
data = [];
|
60
|
+
arry = ts.filter.getOptionSource(c.$table[0], indx, onlyAvail) || [];
|
61
|
+
// build select2 data option
|
62
|
+
$.each(arry, function(i,v){
|
63
|
+
data.push({id: v, text: v});
|
64
|
+
});
|
65
|
+
o.data = data;
|
66
|
+
};
|
67
|
+
|
68
|
+
// get filter-match class from option
|
69
|
+
$header.toggleClass('filter-match', o.match);
|
70
|
+
if (o.cellText) {
|
71
|
+
$cell.prepend('<label>' + o.cellText + '</label>');
|
72
|
+
}
|
73
|
+
|
74
|
+
// don't add default in table options if either ajax or
|
75
|
+
// data options are already defined
|
76
|
+
if (!(o.ajax && !$.isEmptyObject(o.ajax)) && !o.data) {
|
77
|
+
updateOptions();
|
78
|
+
if (onlyAvail) {
|
79
|
+
c.$table.bind('filterEnd', function(){
|
80
|
+
updateOptions();
|
81
|
+
$cell.add($shcell).find('.select2').select2(o);
|
82
|
+
});
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
// add a select2 hidden input!
|
87
|
+
$('<input class="select2 select2-' + indx + '" type="hidden" />')
|
88
|
+
.val(o.value)
|
89
|
+
.appendTo($cell)
|
90
|
+
.select2(o)
|
91
|
+
.bind('change', function(){
|
92
|
+
updateSelect2();
|
93
|
+
});
|
94
|
+
|
95
|
+
// update select2 from filter hidden input, in case of saved filters
|
96
|
+
c.$table.bind('filterFomatterUpdate', function(){
|
97
|
+
// value = '/(x$|y$)/' => 'x,y'
|
98
|
+
var val = c.$table.data('lastSearch')[indx] || '';
|
99
|
+
val = val.replace(/[/()$]/g, '').split('|');
|
100
|
+
$cell.find('.select2').select2('val', val);
|
101
|
+
updateSelect2(val, true);
|
102
|
+
});
|
103
|
+
|
104
|
+
// has sticky headers?
|
105
|
+
c.$table.bind('stickyHeadersInit', function(){
|
106
|
+
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
|
107
|
+
// add a select2!
|
108
|
+
$('<input class="select2 select2-' + indx + '" type="hidden">')
|
109
|
+
.val(o.value)
|
110
|
+
.appendTo($shcell)
|
111
|
+
.select2(o)
|
112
|
+
.bind('change', function(){
|
113
|
+
$cell.find('.select2').select2('val', $shcell.find('.select2').select2('val') );
|
114
|
+
updateSelect2();
|
115
|
+
});
|
116
|
+
if (o.cellText) {
|
117
|
+
$shcell.prepend('<label>' + o.cellText + '</label>');
|
118
|
+
}
|
119
|
+
|
120
|
+
});
|
121
|
+
|
122
|
+
// on reset
|
123
|
+
c.$table.bind('filterReset', function(){
|
124
|
+
$cell.find('.select2').select2('val', o.value || '');
|
125
|
+
setTimeout(function(){
|
126
|
+
updateSelect2();
|
127
|
+
}, 0);
|
128
|
+
});
|
129
|
+
|
130
|
+
updateSelect2();
|
131
|
+
return $input;
|
132
|
+
};
|
133
|
+
|
134
|
+
})(jQuery);
|
data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets-filter-formatter.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Filter widget formatter functions - updated
|
1
|
+
/*! Filter widget formatter functions - updated 4/23/2014 (v2.16.0)
|
2
2
|
* requires: tableSorter 2.15+ and jQuery 1.4.3+
|
3
3
|
*
|
4
4
|
* uiSpinner (jQuery UI spinner)
|
@@ -20,6 +20,7 @@ var ts = $.tablesorter || {},
|
|
20
20
|
// compare option selector class name (jQuery selector)
|
21
21
|
compareSelect = '.compare-select',
|
22
22
|
|
23
|
+
|
23
24
|
tsff = ts.filterFormatter = {
|
24
25
|
|
25
26
|
addCompare: function($cell, indx, options){
|
@@ -87,7 +88,7 @@ tsff = ts.filterFormatter = {
|
|
87
88
|
v = ui && ui.value && ts.formatFloat((ui.value + '').replace(/[><=]/g,'')) ||
|
88
89
|
$cell.find('.spinner').val() || o.value,
|
89
90
|
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
|
90
|
-
searchType = ui && typeof ui.delayed === 'boolean' ? ui.delayed : c.$table[0].hasInitialized ? o.delayed : true;
|
91
|
+
searchType = ui && typeof ui.delayed === 'boolean' ? ui.delayed : c.$table[0].hasInitialized ? o.delayed || '' : true;
|
91
92
|
if (o.addToggle) {
|
92
93
|
chkd = $cell.find('.toggle').is(':checked');
|
93
94
|
}
|
@@ -244,7 +245,7 @@ tsff = ts.filterFormatter = {
|
|
244
245
|
val = o.compare ? v : v === o.min ? o.allText : v,
|
245
246
|
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
|
246
247
|
result = compare + val,
|
247
|
-
searchType = ui && typeof ui.delayed === 'boolean' ? ui.delayed : c.$table[0].hasInitialized ? o.delayed : true;
|
248
|
+
searchType = ui && typeof ui.delayed === 'boolean' ? ui.delayed : c.$table[0].hasInitialized ? o.delayed || '' : true;
|
248
249
|
if (o.valueToHeader) {
|
249
250
|
// add range indication to the header cell above!
|
250
251
|
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(' (' + result + ')');
|
@@ -391,7 +392,7 @@ tsff = ts.filterFormatter = {
|
|
391
392
|
result = val[0] + ' - ' + val[1],
|
392
393
|
// make range an empty string if entire range is covered so the filter row will hide (if set)
|
393
394
|
range = val[0] === o.min && val[1] === o.max ? '' : result,
|
394
|
-
searchType = ui && typeof ui.delayed === 'boolean' ? ui.delayed : c.$table[0].hasInitialized ? o.delayed : true;
|
395
|
+
searchType = ui && typeof ui.delayed === 'boolean' ? ui.delayed : c.$table[0].hasInitialized ? o.delayed || '': true;
|
395
396
|
if (o.valueToHeader) {
|
396
397
|
// add range indication to the header cell above (if not using the css method)!
|
397
398
|
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.currange').html(' (' + result + ')');
|
@@ -511,12 +512,12 @@ tsff = ts.filterFormatter = {
|
|
511
512
|
t, $shcell = [],
|
512
513
|
|
513
514
|
// this function updates the hidden input
|
514
|
-
date1Compare = function(
|
515
|
+
date1Compare = function(notrigger) {
|
515
516
|
var date, query,
|
516
|
-
getdate =
|
517
|
+
getdate = $date.datepicker('getDate') || '',
|
517
518
|
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
|
518
|
-
searchType = c.$table[0].hasInitialized ? o.delayed : true;
|
519
|
-
$date.datepicker('setDate', getdate === '' ?
|
519
|
+
searchType = c.$table[0].hasInitialized ? o.delayed || '': true;
|
520
|
+
$date.datepicker('setDate', getdate === '' ? '' : getdate);
|
520
521
|
if (getdate === '') { notrigger = false; }
|
521
522
|
date = $date.datepicker('getDate');
|
522
523
|
query = date ? ( o.endOfDay && /<=/.test(compare) ? date.setHours(23, 59, 59) : date.getTime() ) || '' : '';
|
@@ -539,7 +540,7 @@ tsff = ts.filterFormatter = {
|
|
539
540
|
|
540
541
|
// Add date range picker
|
541
542
|
t = '<input type="text" class="date date' + indx + '" placeholder="' +
|
542
|
-
($hdr.data('placeholder') || $hdr.attr('data-placeholder') || '') + '" />';
|
543
|
+
($hdr.data('placeholder') || $hdr.attr('data-placeholder') || c.widgetOptions.filter_placeholder.search || '') + '" />';
|
543
544
|
$date = $(t).appendTo($cell);
|
544
545
|
|
545
546
|
// add callbacks; preserve added callbacks
|
@@ -556,7 +557,7 @@ tsff = ts.filterFormatter = {
|
|
556
557
|
if ($.isArray(o.compare)) {
|
557
558
|
$cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
|
558
559
|
}
|
559
|
-
$cell.add($shcell).find('.date').val(o.defaultDate).datepicker('setDate',
|
560
|
+
$cell.add($shcell).find('.date').val(o.defaultDate).datepicker('setDate', o.defaultDate);
|
560
561
|
setTimeout(function(){
|
561
562
|
date1Compare();
|
562
563
|
}, 0);
|
@@ -568,15 +569,17 @@ tsff = ts.filterFormatter = {
|
|
568
569
|
if (/\s+-\s+/.test(v)) {
|
569
570
|
// date range found; assume an exact match on one day
|
570
571
|
$cell.find(compareSelect).val('=');
|
571
|
-
num =
|
572
|
+
num = v.split(/\s+-\s+/)[0];
|
572
573
|
$date.datepicker( 'setDate', num );
|
573
574
|
} else {
|
574
575
|
num = (tsff.updateCompare($cell, $input, o)[1]).toString() || '';
|
575
576
|
// differeniate 1388556000000 from 1/1/2014 using \d{5} regex
|
576
|
-
num = num !== '' ?
|
577
|
+
num = num !== '' ? /\d{5}/g.test(num) ? Number(num) : num || '' : '';
|
577
578
|
}
|
578
579
|
$cell.add($shcell).find('.date').datepicker( 'setDate', num );
|
579
|
-
|
580
|
+
setTimeout(function(){
|
581
|
+
date1Compare(true);
|
582
|
+
}, 0);
|
580
583
|
});
|
581
584
|
|
582
585
|
if (o.compare) {
|
@@ -628,8 +631,11 @@ tsff = ts.filterFormatter = {
|
|
628
631
|
changeYear : true,
|
629
632
|
numberOfMonths : 1
|
630
633
|
}, defDate),
|
631
|
-
t,
|
634
|
+
t, closeDate, $shcell = [],
|
632
635
|
c = $cell.closest('table')[0].config,
|
636
|
+
validDate = function(d){
|
637
|
+
return d instanceof Date && isFinite(d);
|
638
|
+
},
|
633
639
|
// Add a hidden input to hold the range values
|
634
640
|
$input = $('<input class="dateRange" type="hidden">')
|
635
641
|
.appendTo($cell)
|
@@ -639,69 +645,60 @@ tsff = ts.filterFormatter = {
|
|
639
645
|
if (v.match(' - ')) {
|
640
646
|
v = v.split(' - ');
|
641
647
|
$cell.find('.dateTo').val(v[1]);
|
642
|
-
|
648
|
+
closeDate(v[0]);
|
643
649
|
} else if (v.match('>=')) {
|
644
|
-
|
650
|
+
closeDate( v.replace('>=', '') );
|
645
651
|
} else if (v.match('<=')) {
|
646
|
-
|
652
|
+
closeDate( v.replace('<=', '') );
|
647
653
|
}
|
648
|
-
})
|
654
|
+
}),
|
649
655
|
|
650
656
|
// make sure we're using parsed dates in the search
|
651
|
-
$cell.closest('thead').find('th[data-column=' + indx + ']').addClass('filter-parsed');
|
657
|
+
$hdr = $cell.closest('thead').find('th[data-column=' + indx + ']').addClass('filter-parsed');
|
652
658
|
// Add date range picker
|
653
|
-
t = '<label>' + o.textFrom + '</label><input type="text" class="dateFrom"
|
659
|
+
t = '<label>' + o.textFrom + '</label><input type="text" class="dateFrom" placeholder="' +
|
660
|
+
($hdr.data('placeholderFrom') || $hdr.attr('data-placeholder-from') || c.widgetOptions.filter_placeholder.from || '') + '" />' +
|
661
|
+
'<label>' + o.textTo + '</label><input type="text" class="dateTo" placeholder="' +
|
662
|
+
($hdr.data('placeholderTo') || $hdr.attr('data-placeholder-to') || c.widgetOptions.filter_placeholder.to || '') + '" />';
|
654
663
|
$(t).appendTo($cell);
|
655
664
|
|
656
665
|
// add callbacks; preserve added callbacks
|
657
666
|
o.oldonClose = o.onClose;
|
658
667
|
|
659
|
-
|
660
|
-
|
661
|
-
closeFrom = o.onClose = function( selectedDate, ui ) {
|
668
|
+
closeDate = o.onClose = function( selectedDate, ui ) {
|
662
669
|
var range,
|
663
|
-
from =
|
664
|
-
to = $cell.find('.dateTo').datepicker('getDate')
|
665
|
-
|
670
|
+
from = $cell.find('.dateFrom').datepicker('getDate'),
|
671
|
+
to = $cell.find('.dateTo').datepicker('getDate');
|
672
|
+
from = validDate(from) ? from.getTime() : '';
|
673
|
+
to = validDate(to) ? ( o.endOfDay ? to.setHours(23, 59, 59) : to.getTime() ) || '' : '';
|
666
674
|
range = from ? ( to ? from + ' - ' + to : '>=' + from ) : (to ? '<=' + to : '');
|
667
|
-
$cell
|
675
|
+
$cell.add( $shcell )
|
668
676
|
.find('.dateRange').val(range)
|
669
|
-
.trigger('search')
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
if (
|
675
|
-
$shcell
|
676
|
-
.find('.
|
677
|
-
.find('.
|
677
|
+
.trigger('search');
|
678
|
+
// date picker needs date objects
|
679
|
+
from = from ? new Date(from) : '';
|
680
|
+
to = to ? new Date(to) : '';
|
681
|
+
|
682
|
+
if (/<=/.test(range)) {
|
683
|
+
$cell.add( $shcell )
|
684
|
+
.find('.dateFrom').datepicker('option', 'maxDate', to ).end()
|
685
|
+
.find('.dateTo').datepicker('option', 'minDate', null).datepicker('setDate', to);
|
686
|
+
} else if (/>=/.test(range)) {
|
687
|
+
$cell.add( $shcell )
|
688
|
+
.find('.dateFrom').datepicker('option', 'maxDate', null).datepicker('setDate', from).end()
|
689
|
+
.find('.dateTo').datepicker('option', 'minDate', from );
|
690
|
+
} else {
|
691
|
+
$cell.add( $shcell )
|
692
|
+
.find('.dateFrom').datepicker('option', 'maxDate', null).datepicker('setDate', from ).end()
|
693
|
+
.find('.dateTo').datepicker('option', 'minDate', null).datepicker('setDate', to);
|
678
694
|
}
|
695
|
+
|
679
696
|
if (typeof o.oldonClose === 'function') { o.oldonClose(selectedDate, ui); }
|
680
697
|
};
|
681
698
|
|
699
|
+
o.defaultDate = o.from || '';
|
682
700
|
$cell.find('.dateFrom').datepicker(o);
|
683
|
-
|
684
701
|
o.defaultDate = o.to || '+7d'; // set to date +7 days from today (if not defined)
|
685
|
-
closeTo = o.onClose = function( selectedDate, ui ) {
|
686
|
-
var range,
|
687
|
-
from = new Date( $cell.find('.dateFrom').datepicker('getDate') ).getTime() || '',
|
688
|
-
to = $cell.find('.dateTo').datepicker('getDate') || '';
|
689
|
-
to = to ? ( o.endOfDay ? to.setHours(23, 59, 59) : to.getTime() ) || '' : '';
|
690
|
-
range = from ? ( to ? from + ' - ' + to : '>=' + from ) : (to ? '<=' + to : '');
|
691
|
-
$cell
|
692
|
-
.find('.dateRange').val(range)
|
693
|
-
.trigger('search').end()
|
694
|
-
.find('.dateFrom').datepicker('option', 'maxDate', selectedDate ).end()
|
695
|
-
.find('.dateTo').val(selectedDate);
|
696
|
-
|
697
|
-
// update sticky header cell
|
698
|
-
if ($shcell.length) {
|
699
|
-
$shcell
|
700
|
-
.find('.dateFrom').datepicker('option', 'maxDate', selectedDate ).end()
|
701
|
-
.find('.dateTo').val(selectedDate);
|
702
|
-
}
|
703
|
-
if (typeof o.oldonClose === 'function') { o.oldonClose(selectedDate, ui); }
|
704
|
-
};
|
705
702
|
$cell.find('.dateTo').datepicker(o);
|
706
703
|
|
707
704
|
// update date compare from hidden input, in case of saved filters
|
@@ -709,7 +706,6 @@ tsff = ts.filterFormatter = {
|
|
709
706
|
var val = $input.val() || '',
|
710
707
|
from = '',
|
711
708
|
to = '';
|
712
|
-
|
713
709
|
// date range
|
714
710
|
if (/\s+-\s+/.test(val)){
|
715
711
|
val = val.split(/\s+-\s+/) || [];
|
@@ -717,14 +713,17 @@ tsff = ts.filterFormatter = {
|
|
717
713
|
to = val[1] || '';
|
718
714
|
} else if (/>=/.test(val)) {
|
719
715
|
// greater than date (to date empty)
|
720
|
-
from =
|
716
|
+
from = val.replace(/>=/, '') || '';
|
721
717
|
} else if (/<=/.test(val)) {
|
722
718
|
// less than date (from date empty)
|
723
|
-
to =
|
719
|
+
to = val.replace(/<=/, '') || '';
|
724
720
|
}
|
725
721
|
$cell.add($shcell).find('.dateFrom').datepicker('setDate', from);
|
726
722
|
$cell.add($shcell).find('.dateTo').datepicker('setDate', to);
|
727
|
-
|
723
|
+
// give datepicker time to process
|
724
|
+
setTimeout(function(){
|
725
|
+
closeDate();
|
726
|
+
}, 0);
|
728
727
|
});
|
729
728
|
|
730
729
|
// has sticky headers?
|
@@ -733,18 +732,21 @@ tsff = ts.filterFormatter = {
|
|
733
732
|
$shcell.append(t);
|
734
733
|
|
735
734
|
// add a jQuery datepicker!
|
736
|
-
o.
|
735
|
+
o.defaultDate = o.from || '';
|
736
|
+
$shcell.find('.dateFrom').datepicker(o);
|
737
|
+
|
738
|
+
o.defaultDate = o.to || '+7d';
|
737
739
|
$shcell.find('.dateTo').datepicker(o);
|
738
740
|
|
739
|
-
o.defaultDate = localfrom;
|
740
|
-
o.onClose = closeFrom;
|
741
|
-
$shcell.find('.dateFrom').datepicker(o);
|
742
741
|
});
|
743
742
|
|
744
743
|
// on reset
|
745
744
|
$cell.closest('table').bind('filterReset', function(){
|
746
745
|
$cell.add($shcell).find('.dateFrom').val('').datepicker('setDate', o.from );
|
747
746
|
$cell.add($shcell).find('.dateTo').val('').datepicker('setDate', o.to );
|
747
|
+
setTimeout(function(){
|
748
|
+
closeDate();
|
749
|
+
}, 0);
|
748
750
|
});
|
749
751
|
|
750
752
|
// return the hidden input so the filter widget has a reference to it
|
@@ -781,7 +783,7 @@ tsff = ts.filterFormatter = {
|
|
781
783
|
var chkd = o.addToggle ? $cell.find('.toggle').is(':checked') : true,
|
782
784
|
v = $cell.find('.number').val(),
|
783
785
|
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
|
784
|
-
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) : true;
|
786
|
+
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
|
785
787
|
$input
|
786
788
|
// add equal to the beginning, so we filter exact numbers
|
787
789
|
.val( !o.addToggle || chkd ? (compare ? compare : o.exactMatch ? '=' : '') + v : '' )
|
@@ -913,7 +915,7 @@ tsff = ts.filterFormatter = {
|
|
913
915
|
v = ( typeof v === "undefined" ? $input.val() : v ).toString().replace(/[<>=]/g,'') || o.value;
|
914
916
|
var compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
|
915
917
|
t = ' (' + (compare ? compare + v : v == o.min ? o.allText : v) + ')',
|
916
|
-
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) : true;
|
918
|
+
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
|
917
919
|
$cell.find('input[type=hidden]')
|
918
920
|
// add equal to the beginning, so we filter exact numbers
|
919
921
|
.val( ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) ) )
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! tableSorter 2.
|
1
|
+
/*! tableSorter 2.16+ widgets - updated 4/23/2014 (v2.16.0)
|
2
2
|
*
|
3
3
|
* Column Styles
|
4
4
|
* Column Filters
|
@@ -360,9 +360,11 @@ ts.addWidget({
|
|
360
360
|
filter_ignoreCase : true, // if true, make all searches case-insensitive
|
361
361
|
filter_liveSearch : true, // if true, search column content while the user types (with a delay)
|
362
362
|
filter_onlyAvail : 'filter-onlyAvail', // a header with a select dropdown & this class name will only show available (visible) options within the drop down
|
363
|
+
filter_placeholder : { search : '', select : '' }, // default placeholder text (overridden by any header "data-placeholder" setting)
|
363
364
|
filter_reset : null, // jQuery selector string of an element used to reset the filters
|
364
365
|
filter_saveFilters : false, // Use the $.tablesorter.storage utility to save the most recent filters
|
365
366
|
filter_searchDelay : 300, // typing delay in milliseconds before starting a search
|
367
|
+
filter_selectSource : null, // include a function to return an array of values to be added to the column filter select
|
366
368
|
filter_startsWith : false, // if true, filter start from the beginning of the cell contents
|
367
369
|
filter_useParsedData : false, // filter all data using parsed content
|
368
370
|
filter_serversideFiltering : false, // if true, server-side filtering should be performed because client-side filtering will be disabled, but the ui and events will still be used.
|
@@ -584,12 +586,20 @@ ts.filter = {
|
|
584
586
|
|
585
587
|
// reset button/link
|
586
588
|
if (wo.filter_reset) {
|
587
|
-
$
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
})
|
589
|
+
if (wo.filter_reset instanceof $) {
|
590
|
+
// reset contains a jQuery object, bind to it
|
591
|
+
wo.filter_reset.click(function(){
|
592
|
+
c.$table.trigger('filterReset');
|
593
|
+
});
|
594
|
+
} else if ($(wo.filter_reset).length) {
|
595
|
+
// reset is a jQuery selector, use event delegation
|
596
|
+
$(document)
|
597
|
+
.undelegate(wo.filter_reset, 'click.tsfilter')
|
598
|
+
.delegate(wo.filter_reset, 'click.tsfilter', function() {
|
599
|
+
// trigger a reset event, so other functions (filterFormatter) know when to reset
|
600
|
+
c.$table.trigger('filterReset');
|
601
|
+
});
|
602
|
+
}
|
593
603
|
}
|
594
604
|
if (wo.filter_functions) {
|
595
605
|
// column = column # (string)
|
@@ -604,7 +614,7 @@ ts.filter = {
|
|
604
614
|
for (string in wo.filter_functions[column]) {
|
605
615
|
if (typeof string === 'string') {
|
606
616
|
options += options === '' ?
|
607
|
-
'<option value="">' + ($header.data('placeholder') || $header.attr('data-placeholder') ||
|
617
|
+
'<option value="">' + ($header.data('placeholder') || $header.attr('data-placeholder') || wo.filter_placeholder.select || '') + '</option>' : '';
|
608
618
|
options += '<option value="' + string + '">' + string + '</option>';
|
609
619
|
}
|
610
620
|
}
|
@@ -715,7 +725,7 @@ ts.filter = {
|
|
715
725
|
buildFilter = $('<input type="search">').appendTo( c.$filters.eq(column) );
|
716
726
|
}
|
717
727
|
if (buildFilter) {
|
718
|
-
buildFilter.attr('placeholder', $header.data('placeholder') || $header.attr('data-placeholder') || '');
|
728
|
+
buildFilter.attr('placeholder', $header.data('placeholder') || $header.attr('data-placeholder') || wo.filter_placeholder.search || '');
|
719
729
|
}
|
720
730
|
}
|
721
731
|
if (buildFilter) {
|
@@ -725,7 +735,7 @@ ts.filter = {
|
|
725
735
|
wo.filter_cssFilter ) || '';
|
726
736
|
buildFilter.addClass( ts.css.filter + ' ' + name ).attr('data-column', column);
|
727
737
|
if (disabled) {
|
728
|
-
buildFilter.addClass('disabled')[0].disabled = true; // disabled!
|
738
|
+
buildFilter.attr('placeholder', '').addClass('disabled')[0].disabled = true; // disabled!
|
729
739
|
}
|
730
740
|
}
|
731
741
|
}
|
@@ -753,7 +763,7 @@ ts.filter = {
|
|
753
763
|
.attr('data-lastSearchTime', new Date().getTime())
|
754
764
|
.unbind('keyup search change '.split(' ').join(c.namespace + 'filter '))
|
755
765
|
// include change for select - fixes #473
|
756
|
-
.bind('keyup search change '.split(' ').join(c.namespace + 'filter '), function(event
|
766
|
+
.bind('keyup search change '.split(' ').join(c.namespace + 'filter '), function(event) {
|
757
767
|
$(this).attr('data-lastSearchTime', new Date().getTime());
|
758
768
|
// emulate what webkit does.... escape clears the filter
|
759
769
|
if (event.which === 27) {
|
@@ -865,20 +875,23 @@ ts.filter = {
|
|
865
875
|
if ($tbodies.eq(tbodyIndex).hasClass(c.cssInfoBlock || ts.css.info)) { continue; } // ignore info blocks, issue #264
|
866
876
|
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true);
|
867
877
|
// skip child rows & widget added (removable) rows - fixes #448 thanks to @hempel!
|
868
|
-
$rows = $tbody.children('tr').not(c.selectorRemove);
|
878
|
+
// $rows = $tbody.children('tr').not(c.selectorRemove);
|
879
|
+
columnIndex = c.columns;
|
880
|
+
// convert stored rows into a jQuery object
|
881
|
+
$rows = true ? $( $.map(c.cache[tbodyIndex].normalized, function(el){ return el[columnIndex].$row.get(); }) ) : $tbody.children('tr').not(c.selectorRemove);
|
869
882
|
len = $rows.length;
|
870
883
|
if (combinedFilters === '' || wo.filter_serversideFiltering) {
|
871
|
-
$
|
884
|
+
$rows.removeClass(wo.filter_filteredRow).not('.' + c.cssChildRow).show();
|
872
885
|
} else {
|
873
886
|
// optimize searching only through already filtered rows - see #313
|
874
887
|
searchFiltered = true;
|
875
888
|
lastSearch = c.lastSearch || c.$table.data('lastSearch') || [];
|
876
889
|
$.each(filters, function(indx, val) {
|
877
890
|
// check for changes from beginning of filter; but ignore if there is a logical "or" in the string
|
878
|
-
searchFiltered = (val || '').indexOf(lastSearch[indx]
|
891
|
+
searchFiltered = (val || '').indexOf(lastSearch[indx]) === 0 && searchFiltered && !/(\s+or\s+|\|)/g.test(val || '');
|
879
892
|
});
|
880
893
|
// can't search when all rows are hidden - this happens when looking for exact matches
|
881
|
-
if (searchFiltered && $rows.
|
894
|
+
if (searchFiltered && $rows.not('.' + wo.filter_filteredRow).length === 0) { searchFiltered = false; }
|
882
895
|
if ((wo.filter_$anyMatch && wo.filter_$anyMatch.length) || filters[c.columns]) {
|
883
896
|
anyMatch = wo.filter_$anyMatch && wo.filter_$anyMatch.val() || filters[c.columns] || '';
|
884
897
|
if (c.sortLocaleCompare) {
|
@@ -887,7 +900,6 @@ ts.filter = {
|
|
887
900
|
}
|
888
901
|
iAnyMatch = anyMatch.toLowerCase();
|
889
902
|
}
|
890
|
-
|
891
903
|
// loop through the rows
|
892
904
|
cacheIndex = 0;
|
893
905
|
for (rowIndex = 0; rowIndex < len; rowIndex++) {
|
@@ -902,7 +914,7 @@ ts.filter = {
|
|
902
914
|
// checked here so the option can be changed dynamically
|
903
915
|
childRowText = (childRow.length && wo.filter_childRows) ? childRow.text() : '';
|
904
916
|
childRowText = wo.filter_ignoreCase ? childRowText.toLocaleLowerCase() : childRowText;
|
905
|
-
$cells = $rows.eq(rowIndex).children(
|
917
|
+
$cells = $rows.eq(rowIndex).children();
|
906
918
|
|
907
919
|
if (anyMatch) {
|
908
920
|
rowArray = $cells.map(function(i){
|
@@ -919,7 +931,7 @@ ts.filter = {
|
|
919
931
|
}).get();
|
920
932
|
rowText = rowArray.join(' ');
|
921
933
|
iRowText = rowText.toLowerCase();
|
922
|
-
rowCache = c.cache[tbodyIndex].normalized[cacheIndex].join(' ');
|
934
|
+
rowCache = c.cache[tbodyIndex].normalized[cacheIndex].slice(0,-1).join(' ');
|
923
935
|
filterMatched = null;
|
924
936
|
$.each(ts.filter.types, function(type, typeFunction) {
|
925
937
|
if ($.inArray(type, anyMatchNotAllowedTypes) < 0) {
|
@@ -1010,47 +1022,80 @@ ts.filter = {
|
|
1010
1022
|
if (c.debug) {
|
1011
1023
|
ts.benchmark("Completed filter widget search", time);
|
1012
1024
|
}
|
1013
|
-
c.$table.trigger('applyWidgets'); // make sure zebra widget is applied
|
1014
1025
|
c.$table.trigger('filterEnd');
|
1026
|
+
setTimeout(function(){
|
1027
|
+
c.$table.trigger('applyWidgets'); // make sure zebra widget is applied
|
1028
|
+
}, 0);
|
1015
1029
|
},
|
1016
|
-
|
1017
|
-
|
1018
|
-
column = parseInt(column, 10);
|
1019
|
-
var indx, rowIndex, tbodyIndex, len, currentValue, txt, $filters,
|
1020
|
-
c = table.config,
|
1030
|
+
getOptionSource: function(table, column, onlyAvail) {
|
1031
|
+
var c = table.config,
|
1021
1032
|
wo = c.widgetOptions,
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
if (onlyavail && c.cache[tbodyIndex].row[rowIndex][0].className.match(wo.filter_filteredRow)) { continue; }
|
1033
|
-
// get non-normalized cell content
|
1034
|
-
if (wo.filter_useParsedData) {
|
1035
|
-
arry.push( '' + c.cache[tbodyIndex].normalized[rowIndex][column] );
|
1036
|
-
} else {
|
1037
|
-
node = c.cache[tbodyIndex].row[rowIndex][0].cells[column];
|
1038
|
-
if (node) {
|
1039
|
-
arry.push( $.trim( node.textContent || node.innerText || $(node).text() ) );
|
1040
|
-
}
|
1041
|
-
}
|
1042
|
-
}
|
1033
|
+
arry = false,
|
1034
|
+
source = wo.filter_selectSource;
|
1035
|
+
|
1036
|
+
// filter select source option
|
1037
|
+
if ($.isFunction(source)) {
|
1038
|
+
// OVERALL source
|
1039
|
+
arry = source(table, column, onlyAvail);
|
1040
|
+
} else if ($.type(source) === 'object' && source.hasOwnProperty(column)) {
|
1041
|
+
// custom select source function for a SPECIFIC COLUMN
|
1042
|
+
arry = source[column](table, column, onlyAvail);
|
1043
1043
|
}
|
1044
|
+
if (arry === false) {
|
1045
|
+
// fall back to original method
|
1046
|
+
arry = ts.filter.getOptions(table, column, onlyAvail);
|
1047
|
+
}
|
1048
|
+
|
1044
1049
|
// get unique elements and sort the list
|
1045
1050
|
// if $.tablesorter.sortText exists (not in the original tablesorter),
|
1046
1051
|
// then natural sort the list otherwise use a basic sort
|
1047
1052
|
arry = $.grep(arry, function(value, indx) {
|
1048
1053
|
return $.inArray(value, arry) === indx;
|
1049
1054
|
});
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1055
|
+
return (ts.sortNatural) ? arry.sort(function(a, b) { return ts.sortNatural(a, b); }) : arry.sort(true);
|
1056
|
+
},
|
1057
|
+
getOptions: function(table, column, onlyAvail) {
|
1058
|
+
var rowIndex, tbodyIndex, len, row, cache, cell,
|
1059
|
+
c = table.config,
|
1060
|
+
wo = c.widgetOptions,
|
1061
|
+
$tbodies = c.$table.children('tbody'),
|
1062
|
+
arry = [];
|
1063
|
+
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
|
1064
|
+
if (!$tbodies.eq(tbodyIndex).hasClass(c.cssInfoBlock)) {
|
1065
|
+
cache = c.cache[tbodyIndex];
|
1066
|
+
len = c.cache[tbodyIndex].normalized.length;
|
1067
|
+
// loop through the rows
|
1068
|
+
for (rowIndex = 0; rowIndex < len; rowIndex++) {
|
1069
|
+
// get cached row from cache.row (old) or row data object (new; last item in normalized array)
|
1070
|
+
row = cache.row ? cache.row[rowIndex] : cache.normalized[rowIndex][c.columns].$row[0];
|
1071
|
+
// check if has class filtered
|
1072
|
+
if (onlyAvail && row.className.match(wo.filter_filteredRow)) { continue; }
|
1073
|
+
// get non-normalized cell content
|
1074
|
+
if (wo.filter_useParsedData) {
|
1075
|
+
arry.push( '' + cache.normalized[rowIndex][column] );
|
1076
|
+
} else {
|
1077
|
+
cell = row.cells[column];
|
1078
|
+
if (cell) {
|
1079
|
+
arry.push( $.trim( cell.textContent || cell.innerText || $(cell).text() ) );
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
}
|
1083
|
+
}
|
1084
|
+
}
|
1085
|
+
return arry;
|
1086
|
+
},
|
1087
|
+
buildSelect: function(table, column, updating, onlyAvail) {
|
1088
|
+
if (!table.config.cache || $.isEmptyObject(table.config.cache)) { return; }
|
1089
|
+
column = parseInt(column, 10);
|
1090
|
+
var indx, txt, $filters,
|
1091
|
+
c = table.config,
|
1092
|
+
wo = c.widgetOptions,
|
1093
|
+
node = c.$headers.filter('[data-column="' + column + '"]:last'),
|
1094
|
+
// t.data('placeholder') won't work in jQuery older than 1.4.3
|
1095
|
+
options = '<option value="">' + ( node.data('placeholder') || node.attr('data-placeholder') || wo.filter_placeholder.select || '' ) + '</option>',
|
1096
|
+
arry = ts.filter.getOptionSource(table, column, onlyAvail),
|
1097
|
+
// Get curent filter value
|
1098
|
+
currentValue = c.$table.find('thead').find('select.' + ts.css.filter + '[data-column="' + column + '"]').val();
|
1054
1099
|
|
1055
1100
|
// build option list
|
1056
1101
|
for (indx = 0; indx < arry.length; indx++) {
|
@@ -1150,7 +1195,8 @@ ts.setFilters = function(table, filter, apply, skipFirst) {
|
|
1150
1195
|
if (c && apply) {
|
1151
1196
|
// ensure new set filters are applied, even if the search is the same
|
1152
1197
|
c.lastCombinedFilter = null;
|
1153
|
-
c.$table
|
1198
|
+
ts.filter.searching(c.$table[0], filter, skipFirst);
|
1199
|
+
c.$table.trigger('filterFomatterUpdate');
|
1154
1200
|
}
|
1155
1201
|
return !!valid;
|
1156
1202
|
};
|
@@ -1235,7 +1281,8 @@ ts.addWidget({
|
|
1235
1281
|
if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
|
1236
1282
|
// clear out cloned table, except for sticky header
|
1237
1283
|
// include caption & filter row (fixes #126 & #249) - don't remove cells to get correct cell indexing
|
1238
|
-
$stickyTable.find('thead:gt(0), tr.sticky-false
|
1284
|
+
$stickyTable.find('thead:gt(0), tr.sticky-false').hide();
|
1285
|
+
$stickyTable.find('tbody, tfoot').remove();
|
1239
1286
|
if (!wo.stickyHeaders_includeCaption) {
|
1240
1287
|
$stickyTable.find('caption').remove();
|
1241
1288
|
} else {
|