jquery-tablesorter 1.19.4 → 1.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/jquery-tablesorter/version.rb +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +10 -10
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +210 -108
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +151 -74
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +59 -34
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +62 -32
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +15 -12
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +6 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +53 -28
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +154 -76
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +9 -9
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +3 -3
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +2 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-view.js +2 -2
- metadata +2 -2
@@ -230,7 +230,7 @@
|
|
230
230
|
tsColSel.adjustColspans( c, wo );
|
231
231
|
// trigger columnUpdate if auto is true (it gets skipped in updateCols()
|
232
232
|
if (colSel.auto) {
|
233
|
-
c.$table.
|
233
|
+
c.$table.triggerHandler(wo.columnSelector_updated);
|
234
234
|
}
|
235
235
|
},
|
236
236
|
addSelectors: function( prefix, column ) {
|
@@ -318,7 +318,7 @@
|
|
318
318
|
ts.storage( c.$table[0], 'tablesorter-columnSelector', colSel.states );
|
319
319
|
}
|
320
320
|
tsColSel.adjustColspans( c, wo );
|
321
|
-
c.$table.
|
321
|
+
c.$table.triggerHandler(wo.columnSelector_updated);
|
322
322
|
},
|
323
323
|
|
324
324
|
setUpColspan: function(c, wo) {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Widget: editable - updated
|
1
|
+
/*! Widget: editable - updated 12/13/2015 (v2.25.0) *//*
|
2
2
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
3
|
* by Rob Garrison
|
4
4
|
*/
|
@@ -222,17 +222,20 @@
|
|
222
222
|
.data( 'before', valid )
|
223
223
|
.data( 'original', valid )
|
224
224
|
.trigger( 'change' );
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
225
|
+
// prevent error if table was destroyed - see #1099
|
226
|
+
if ( c.table.hasInitialized ) {
|
227
|
+
$.tablesorter.updateCell( c, $this.closest( 'td' ), false, function() {
|
228
|
+
if ( wo.editable_autoResort ) {
|
229
|
+
setTimeout( function() {
|
230
|
+
$.tablesorter.sortOn( c, c.sortList, function() {
|
231
|
+
tse.editComplete( c, wo, c.$table.data( 'contentFocused' ), true );
|
232
|
+
}, true );
|
233
|
+
}, 10 );
|
234
|
+
} else {
|
235
|
+
tse.editComplete( c, wo, c.$table.data( 'contentFocused' ) );
|
236
|
+
}
|
237
|
+
});
|
238
|
+
}
|
236
239
|
return false;
|
237
240
|
}
|
238
241
|
} else if ( !valid && e.type !== 'keydown' ) {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Widget: filter, insideRange filter type - updated
|
1
|
+
/*! Widget: filter, insideRange filter type - updated 12/10/2015 (v2.25.0) */
|
2
2
|
;(function($){
|
3
3
|
'use strict';
|
4
4
|
|
@@ -15,14 +15,15 @@
|
|
15
15
|
};
|
16
16
|
|
17
17
|
ts.filter.types.insideRange = function( c, data ) {
|
18
|
-
|
18
|
+
// don't look for an inside range if "any" match is enabled... multiple "-" really screw things up
|
19
|
+
if ( !data.anyMatch && isDigit.test( data.iFilter ) && range.test( data.iExact ) ) {
|
19
20
|
var t, val, low, high,
|
20
21
|
index = data.index,
|
21
22
|
cell = data.$cells[ index ],
|
22
23
|
parts = data.iExact.split( range ),
|
23
|
-
format = c.parsers[data.index].format;
|
24
|
-
// the cell does not contain a range
|
25
|
-
if ( parts && parts.length < 2 ) {
|
24
|
+
format = c.parsers[data.index] && c.parsers[data.index].format;
|
25
|
+
// the cell does not contain a range or the parser isn't defined
|
26
|
+
if ( parts && parts.length < 2 || typeof format !== 'function' ) {
|
26
27
|
return null;
|
27
28
|
}
|
28
29
|
// format each side part of the range using the assigned parser
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Widget: filter - updated
|
1
|
+
/*! Widget: filter - updated 12/13/2015 (v2.25.0) *//*
|
2
2
|
* Requires tablesorter v2.8+ and jQuery 1.7+
|
3
3
|
* by Rob Garrison
|
4
4
|
*/
|
@@ -208,7 +208,7 @@
|
|
208
208
|
table = c.table,
|
209
209
|
parsed = data.parsed[ data.index ],
|
210
210
|
query = ts.formatFloat( data.iFilter.replace( tsfRegex.operators, '' ), table ),
|
211
|
-
parser = c.parsers[ data.index ],
|
211
|
+
parser = c.parsers[ data.index ] || {},
|
212
212
|
savedSearch = query;
|
213
213
|
// parse filter value in case we're comparing numbers ( dates )
|
214
214
|
if ( parsed || parser.type === 'numeric' ) {
|
@@ -348,6 +348,7 @@
|
|
348
348
|
|
349
349
|
var options, string, txt, $header, column, filters, val, fxn, noSelect;
|
350
350
|
c.$table.addClass( 'hasFilters' );
|
351
|
+
c.lastSearch = [];
|
351
352
|
|
352
353
|
// define timers so using clearTimeout won't cause an undefined error
|
353
354
|
wo.filter_searchTimer = null;
|
@@ -430,7 +431,7 @@
|
|
430
431
|
if ( wo.filter_reset instanceof $ ) {
|
431
432
|
// reset contains a jQuery object, bind to it
|
432
433
|
wo.filter_reset.click( function() {
|
433
|
-
c.$table.
|
434
|
+
c.$table.triggerHandler( 'filterReset' );
|
434
435
|
});
|
435
436
|
} else if ( $( wo.filter_reset ).length ) {
|
436
437
|
// reset is a jQuery selector, use event delegation
|
@@ -438,7 +439,7 @@
|
|
438
439
|
.undelegate( wo.filter_reset, 'click' + c.namespace + 'filter' )
|
439
440
|
.delegate( wo.filter_reset, 'click' + c.namespace + 'filter', function() {
|
440
441
|
// trigger a reset event, so other functions ( filter_formatter ) know when to reset
|
441
|
-
c.$table.
|
442
|
+
c.$table.triggerHandler( 'filterReset' );
|
442
443
|
});
|
443
444
|
}
|
444
445
|
}
|
@@ -540,7 +541,7 @@
|
|
540
541
|
ts.setFilters( table, filters, true );
|
541
542
|
}
|
542
543
|
}
|
543
|
-
c.$table.
|
544
|
+
c.$table.triggerHandler( 'filterFomatterUpdate' );
|
544
545
|
// trigger init after setTimeout to prevent multiple filterStart/End/Init triggers
|
545
546
|
setTimeout( function() {
|
546
547
|
if ( !wo.filter_initialized ) {
|
@@ -550,7 +551,7 @@
|
|
550
551
|
});
|
551
552
|
// if filter widget is added after pager has initialized; then set filter init flag
|
552
553
|
if ( c.pager && c.pager.initialized && !wo.filter_initialized ) {
|
553
|
-
c.$table.
|
554
|
+
c.$table.triggerHandler( 'filterFomatterUpdate' );
|
554
555
|
setTimeout( function() {
|
555
556
|
tsf.filterInitComplete( c );
|
556
557
|
}, 100 );
|
@@ -573,7 +574,7 @@
|
|
573
574
|
count = 0,
|
574
575
|
completed = function() {
|
575
576
|
wo.filter_initialized = true;
|
576
|
-
c.$table.
|
577
|
+
c.$table.triggerHandler( 'filterInit', c );
|
577
578
|
tsf.findRows( c.table, c.$table.data( 'lastSearch' ) || [] );
|
578
579
|
};
|
579
580
|
if ( $.isEmptyObject( wo.filter_formatter ) ) {
|
@@ -628,7 +629,7 @@
|
|
628
629
|
for ( indx = 0; indx <= c.columns; indx++ ) {
|
629
630
|
// include data-column='all' external filters
|
630
631
|
col = indx === c.columns ? 'all' : indx;
|
631
|
-
filters[indx] = $filters
|
632
|
+
filters[ indx ] = $filters
|
632
633
|
.filter( '[data-column="' + col + '"]' )
|
633
634
|
.attr( wo.filter_defaultAttrib ) || filters[indx] || '';
|
634
635
|
}
|
@@ -650,11 +651,12 @@
|
|
650
651
|
buildFilter = '<tr role="row" class="' + tscss.filterRow + ' ' + c.cssIgnoreRow + '">';
|
651
652
|
for ( column = 0; column < columns; column++ ) {
|
652
653
|
if ( c.$headerIndexed[ column ].length ) {
|
653
|
-
buildFilter += '<td data-column="' + column + '"';
|
654
654
|
// account for entire column set with colspan. See #1047
|
655
655
|
tmp = c.$headerIndexed[ column ] && c.$headerIndexed[ column ][0].colSpan || 0;
|
656
656
|
if ( tmp > 1 ) {
|
657
|
-
buildFilter += ' colspan="' + tmp + '"';
|
657
|
+
buildFilter += '<td data-column="' + column + '-' + ( column + tmp - 1 ) + '" colspan="' + tmp + '"';
|
658
|
+
} else {
|
659
|
+
buildFilter += '<td data-column="' + column + '"';
|
658
660
|
}
|
659
661
|
if ( arry ) {
|
660
662
|
buildFilter += ( cellFilter[ column ] ? ' class="' + cellFilter[ column ] + '"' : '' );
|
@@ -673,7 +675,8 @@
|
|
673
675
|
// assuming last cell of a column is the main column
|
674
676
|
$header = c.$headerIndexed[ column ];
|
675
677
|
if ( $header && $header.length ) {
|
676
|
-
$filter = c.$filters.filter( '[data-column="' + column + '"]' );
|
678
|
+
// $filter = c.$filters.filter( '[data-column="' + column + '"]' );
|
679
|
+
$filter = tsf.getColumnElm( c, c.$filters, column );
|
677
680
|
ffxn = ts.getColumnData( table, wo.filter_functions, column );
|
678
681
|
makeSelect = ( wo.filter_functions && ffxn && typeof ffxn !== 'function' ) ||
|
679
682
|
$header.hasClass( 'filter-select' );
|
@@ -713,7 +716,8 @@
|
|
713
716
|
name = ( $.isArray( wo.filter_cssFilter ) ?
|
714
717
|
( typeof wo.filter_cssFilter[column] !== 'undefined' ? wo.filter_cssFilter[column] || '' : '' ) :
|
715
718
|
wo.filter_cssFilter ) || '';
|
716
|
-
|
719
|
+
// copy data-column from table cell (it will include colspan)
|
720
|
+
buildFilter.addClass( tscss.filter + ' ' + name ).attr( 'data-column', $filter.attr( 'data-column' ) );
|
717
721
|
if ( disabled ) {
|
718
722
|
buildFilter.attr( 'placeholder', '' ).addClass( tscss.filterDisabled )[0].disabled = true;
|
719
723
|
}
|
@@ -821,7 +825,7 @@
|
|
821
825
|
// show/hide filter row as needed
|
822
826
|
c.$table
|
823
827
|
.find( '.' + tscss.filterRow )
|
824
|
-
.
|
828
|
+
.triggerHandler( combinedFilters === '' ? 'mouseleave' : 'mouseenter' );
|
825
829
|
}
|
826
830
|
// return if the last search is the same; but filter === false when updating the search
|
827
831
|
// see example-widget-filter.html filter toggle buttons
|
@@ -832,6 +836,8 @@
|
|
832
836
|
c.lastCombinedFilter = null;
|
833
837
|
c.lastSearch = [];
|
834
838
|
}
|
839
|
+
// define filter inside it is false
|
840
|
+
filters = filters || [];
|
835
841
|
// convert filters to strings - see #1070
|
836
842
|
filters = Array.prototype.map ?
|
837
843
|
filters.map( String ) :
|
@@ -839,7 +845,7 @@
|
|
839
845
|
filters.join( '\u0000' ).split( '\u0000' );
|
840
846
|
|
841
847
|
if ( wo.filter_initialized ) {
|
842
|
-
c.$table.
|
848
|
+
c.$table.triggerHandler( 'filterStart', [ filters ] );
|
843
849
|
}
|
844
850
|
if ( c.showProcessing ) {
|
845
851
|
// give it time for the processing icon to kick in
|
@@ -920,22 +926,18 @@
|
|
920
926
|
}
|
921
927
|
return $input || $();
|
922
928
|
},
|
923
|
-
|
929
|
+
findRange: function( c, val, ignoreRanges ) {
|
924
930
|
// look for multiple columns '1-3,4-6,8' in data-column
|
925
931
|
var temp, ranges, range, start, end, singles, i, indx, len,
|
926
|
-
|
927
|
-
|
928
|
-
//
|
929
|
-
|
930
|
-
columns = [],
|
931
|
-
val = $.trim( tsf.getLatestSearch( $input ).attr( 'data-column' ) || '' );
|
932
|
-
if ( /^[0-9]+$/.test(val)) {
|
933
|
-
return parseInt( val, 10 );
|
932
|
+
columns = [];
|
933
|
+
if ( /^[0-9]+$/.test( val ) ) {
|
934
|
+
// always return an array
|
935
|
+
return [ parseInt( val, 10 ) ];
|
934
936
|
}
|
935
937
|
// process column range
|
936
|
-
if (
|
938
|
+
if ( !ignoreRanges && /-/.test( val ) ) {
|
937
939
|
ranges = val.match( /(\d+)\s*-\s*(\d+)/g );
|
938
|
-
len = ranges.length;
|
940
|
+
len = ranges ? ranges.length : 0;
|
939
941
|
for ( indx = 0; indx < len; indx++ ) {
|
940
942
|
range = ranges[indx].split( /\s*-\s*/ );
|
941
943
|
start = parseInt( range[0], 10 ) || 0;
|
@@ -954,7 +956,7 @@
|
|
954
956
|
}
|
955
957
|
}
|
956
958
|
// process single columns
|
957
|
-
if (
|
959
|
+
if ( !ignoreRanges && /,/.test( val ) ) {
|
958
960
|
singles = val.split( /\s*,\s*/ );
|
959
961
|
len = singles.length;
|
960
962
|
for ( i = 0; i < len; i++ ) {
|
@@ -974,6 +976,23 @@
|
|
974
976
|
}
|
975
977
|
return columns;
|
976
978
|
},
|
979
|
+
getColumnElm: function( c, $elements, column ) {
|
980
|
+
// data-column may contain multiple columns '1-3,5-6,8'
|
981
|
+
// replaces: c.$filters.filter( '[data-column="' + column + '"]' );
|
982
|
+
return $elements.filter( function() {
|
983
|
+
var cols = tsf.findRange( c, $( this ).attr( 'data-column' ) );
|
984
|
+
return $.inArray( column, cols ) > -1;
|
985
|
+
});
|
986
|
+
},
|
987
|
+
multipleColumns: function( c, $input ) {
|
988
|
+
// look for multiple columns '1-3,4-6,8' in data-column
|
989
|
+
var wo = c.widgetOptions,
|
990
|
+
// only target 'all' column inputs on initialization
|
991
|
+
// & don't target 'all' column inputs if they don't exist
|
992
|
+
targets = wo.filter_initialized || !$input.filter( wo.filter_anyColumnSelector ).length,
|
993
|
+
val = $.trim( tsf.getLatestSearch( $input ).attr( 'data-column' ) || '' );
|
994
|
+
return tsf.findRange( c, val, !targets );
|
995
|
+
},
|
977
996
|
processTypes: function( c, data, vars ) {
|
978
997
|
var ffxn,
|
979
998
|
filterMatched = null,
|
@@ -1087,6 +1106,11 @@
|
|
1087
1106
|
data.filter = ts.replaceAccents( data.filter );
|
1088
1107
|
}
|
1089
1108
|
|
1109
|
+
// replace column specific default filters - see #1088
|
1110
|
+
if ( wo.filter_defaultFilter && tsfRegex.iQuery.test( vars.defaultColFilter[ columnIndex ] ) ) {
|
1111
|
+
data.filter = tsf.defaultFilter( data.filter, vars.defaultColFilter[ columnIndex ] );
|
1112
|
+
}
|
1113
|
+
|
1090
1114
|
// data.iFilter = case insensitive ( if wo.filter_ignoreCase is true ),
|
1091
1115
|
// data.filter = case sensitive
|
1092
1116
|
data.iFilter = wo.filter_ignoreCase ? ( data.filter || '' ).toLowerCase() : data.filter;
|
@@ -1375,7 +1399,8 @@
|
|
1375
1399
|
console.log( 'Completed filter widget search' + ts.benchmark(time) );
|
1376
1400
|
}
|
1377
1401
|
if ( wo.filter_initialized ) {
|
1378
|
-
c.$table.
|
1402
|
+
c.$table.triggerHandler( 'filterBeforeEnd', c );
|
1403
|
+
c.$table.triggerHandler( 'filterEnd', c );
|
1379
1404
|
}
|
1380
1405
|
setTimeout( function() {
|
1381
1406
|
ts.applyWidget( c.table ); // make sure zebra widget is applied
|
@@ -1740,7 +1765,7 @@
|
|
1740
1765
|
c.lastCombinedFilter = null;
|
1741
1766
|
c.lastSearch = [];
|
1742
1767
|
tsf.searching( c.table, filter, skipFirst );
|
1743
|
-
c.$table.
|
1768
|
+
c.$table.triggerHandler( 'filterFomatterUpdate' );
|
1744
1769
|
}
|
1745
1770
|
return !!valid;
|
1746
1771
|
};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! Widget: math - updated
|
1
|
+
/*! Widget: math - updated 12/13/2015 (v2.25.0) *//*
|
2
2
|
* Requires tablesorter v2.16+ and jQuery 1.7+
|
3
3
|
* by Rob Garrison
|
4
4
|
*/
|
@@ -22,37 +22,36 @@
|
|
22
22
|
// name = function returning invalid results
|
23
23
|
// errorIndex = math.error index with an explanation of the error
|
24
24
|
console.log( name, math.error[ errorIndex ] );
|
25
|
-
return c && c.widgetOptions.math_none || '
|
25
|
+
return c && c.widgetOptions.math_none || ''; // text for cell
|
26
26
|
},
|
27
27
|
|
28
|
-
events : ( 'tablesorter-initialized update updateAll updateRows addRows updateCell '
|
29
|
-
|
28
|
+
events : ( 'tablesorter-initialized update updateAll updateRows addRows updateCell filterReset ' )
|
29
|
+
.split(' ').join('.tsmath '),
|
30
30
|
|
31
31
|
processText : function( c, $cell ) {
|
32
|
-
var txt =
|
33
|
-
if ( typeof txt === 'undefined' ) {
|
34
|
-
txt = $cell[0].textContent || $cell.text();
|
35
|
-
}
|
32
|
+
var txt = ts.getElementText( c, $cell, math.getCellIndex( $cell ) );
|
36
33
|
txt = ts.formatFloat( txt.replace( /[^\w,. \-()]/g, '' ), c.table ) || 0;
|
37
34
|
// isNaN('') => false
|
38
35
|
return isNaN( txt ) ? 0 : txt;
|
39
36
|
},
|
40
37
|
|
41
38
|
// get all of the row numerical values in an arry
|
42
|
-
getRow : function( c, $el ) {
|
39
|
+
getRow : function( c, $el, hasFilter ) {
|
43
40
|
var $cells,
|
44
41
|
wo = c.widgetOptions,
|
45
42
|
arry = [],
|
46
43
|
$row = $el.closest( 'tr' ),
|
47
|
-
isFiltered = $row.hasClass( wo.filter_filteredRow || 'filtered' )
|
48
|
-
hasFilter = wo.math_rowFilter;
|
44
|
+
isFiltered = $row.hasClass( wo.filter_filteredRow || 'filtered' );
|
49
45
|
if ( hasFilter ) {
|
50
46
|
$row = $row.filter( hasFilter );
|
51
47
|
}
|
52
|
-
if (
|
48
|
+
if ( hasFilter || !isFiltered ) {
|
53
49
|
$cells = $row.children().not( '[' + wo.math_dataAttrib + '=ignore]' );
|
54
50
|
if ( wo.math_ignore.length ) {
|
55
|
-
$cells = $cells.
|
51
|
+
$cells = $cells.filter( function( indx ) {
|
52
|
+
// using $.inArray is not optimal (needed for IE8)
|
53
|
+
return $.inArray( math.getCellIndex( $( this ) ), wo.math_ignore ) === -1;
|
54
|
+
});
|
56
55
|
}
|
57
56
|
arry = $cells.not( $el ).map( function() {
|
58
57
|
return math.processText( c, $( this ) );
|
@@ -62,31 +61,38 @@
|
|
62
61
|
},
|
63
62
|
|
64
63
|
// get all of the column numerical values in an arry
|
65
|
-
getColumn : function( c, $el, type ) {
|
64
|
+
getColumn : function( c, $el, type, hasFilter ) {
|
66
65
|
var index, $t, $tr, len, $mathRows, mathAbove,
|
67
|
-
arry = [],
|
68
66
|
wo = c.widgetOptions,
|
69
|
-
|
67
|
+
arry = [],
|
68
|
+
$row = $el.closest( 'tr' ),
|
70
69
|
mathAttr = wo.math_dataAttrib,
|
70
|
+
mathIgnore = '[' + mathAttr + '=ignore]',
|
71
71
|
filtered = wo.filter_filteredRow || 'filtered',
|
72
|
-
cIndex =
|
72
|
+
cIndex = math.getCellIndex( $el ),
|
73
|
+
// get all rows to keep row indexing
|
73
74
|
$rows = c.$table.children( 'tbody' ).children(),
|
74
|
-
|
75
|
-
|
76
|
-
|
75
|
+
mathAttrs = [
|
76
|
+
'[' + mathAttr + '^=above]',
|
77
|
+
'[' + mathAttr + '^=below]',
|
78
|
+
'[' + mathAttr + '^=col]',
|
79
|
+
'[' + mathAttr + '^=all]'
|
80
|
+
];
|
77
81
|
if ( type === 'above' ) {
|
78
82
|
len = $rows.index( $row );
|
79
83
|
index = len;
|
80
84
|
while ( index >= 0 ) {
|
81
85
|
$tr = $rows.eq( index );
|
86
|
+
mathAbove = $tr.children().filter( mathAttrs[0] ).length;
|
82
87
|
if ( hasFilter ) {
|
83
|
-
$tr = $tr.filter(
|
88
|
+
$tr = $tr.filter( hasFilter );
|
84
89
|
}
|
85
|
-
$t = $tr.children().filter(
|
86
|
-
|
90
|
+
$t = $tr.children().filter( function( indx ) {
|
91
|
+
return math.getCellIndex( $( this ) ) === cIndex;
|
92
|
+
});
|
87
93
|
// ignore filtered rows & rows with data-math="ignore" (and starting row)
|
88
|
-
if ( ( ( !$tr.hasClass( filtered )
|
89
|
-
$tr.not(
|
94
|
+
if ( ( ( hasFilter || !$tr.hasClass( filtered ) ) &&
|
95
|
+
$tr.not( mathIgnore ).length &&
|
90
96
|
index !== len ) ||
|
91
97
|
mathAbove && index !== len ) {
|
92
98
|
// stop calculating 'above', when encountering another 'above'
|
@@ -103,31 +109,34 @@
|
|
103
109
|
// index + 1 to ignore starting node
|
104
110
|
for ( index = $rows.index( $row ) + 1; index < len; index++ ) {
|
105
111
|
$tr = $rows.eq( index );
|
112
|
+
if ( $tr.children().filter( mathAttrs[1] ).length ) {
|
113
|
+
break;
|
114
|
+
}
|
106
115
|
if ( hasFilter ) {
|
107
116
|
$tr = $tr.filter( hasFilter );
|
108
117
|
}
|
109
|
-
$t = $tr.children().filter(
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
$t.length ) {
|
118
|
+
$t = $tr.children().filter( function( indx ) {
|
119
|
+
return math.getCellIndex( $( this ) ) === cIndex;
|
120
|
+
});
|
121
|
+
if ( ( hasFilter || !$tr.hasClass( filtered ) ) &&
|
122
|
+
$tr.not( mathIgnore ).length &&
|
123
|
+
$t.length ) {
|
116
124
|
arry.push( math.processText( c, $t ) );
|
117
125
|
}
|
118
126
|
}
|
119
|
-
|
120
127
|
} else {
|
121
|
-
$mathRows = $rows.not(
|
128
|
+
$mathRows = $rows.not( mathIgnore );
|
122
129
|
len = $mathRows.length;
|
123
130
|
for ( index = 0; index < len; index++ ) {
|
124
131
|
$tr = $mathRows.eq( index );
|
125
132
|
if ( hasFilter ) {
|
126
133
|
$tr = $tr.filter( hasFilter );
|
127
134
|
}
|
128
|
-
$t = $tr.children().filter(
|
129
|
-
|
130
|
-
|
135
|
+
$t = $tr.children().filter( function( indx ) {
|
136
|
+
return math.getCellIndex( $( this ) ) === cIndex;
|
137
|
+
});
|
138
|
+
if ( ( hasFilter || !$tr.hasClass( filtered ) ) &&
|
139
|
+
$t.not( mathAttrs.join( ',' ) ).length &&
|
131
140
|
!$t.is( $el ) ) {
|
132
141
|
arry.push( math.processText( c, $t ) );
|
133
142
|
}
|
@@ -137,27 +146,27 @@
|
|
137
146
|
},
|
138
147
|
|
139
148
|
// get all of the column numerical values in an arry
|
140
|
-
getAll : function( c ) {
|
149
|
+
getAll : function( c, hasFilter ) {
|
141
150
|
var $t, col, $row, rowIndex, rowLen, $cells, cellIndex, cellLen,
|
142
151
|
arry = [],
|
143
152
|
wo = c.widgetOptions,
|
144
153
|
mathAttr = wo.math_dataAttrib,
|
154
|
+
mathIgnore = '[' + mathAttr + '=ignore]',
|
145
155
|
filtered = wo.filter_filteredRow || 'filtered',
|
146
|
-
|
147
|
-
$rows = c.$table.children( 'tbody' ).children().not( '[' + mathAttr + '=ignore]' );
|
156
|
+
$rows = c.$table.children( 'tbody' ).children().not( mathIgnore );
|
148
157
|
rowLen = $rows.length;
|
149
158
|
for ( rowIndex = 0; rowIndex < rowLen; rowIndex++ ) {
|
150
159
|
$row = $rows.eq( rowIndex );
|
151
160
|
if ( hasFilter ) {
|
152
161
|
$row = $row.filter( hasFilter );
|
153
162
|
}
|
154
|
-
if ( !$row.hasClass( filtered )
|
155
|
-
$cells = $row.children().not(
|
163
|
+
if ( hasFilter || !$row.hasClass( filtered ) ) {
|
164
|
+
$cells = $row.children().not( mathIgnore );
|
156
165
|
cellLen = $cells.length;
|
157
166
|
// $row.children().each(function(){
|
158
167
|
for ( cellIndex = 0; cellIndex < cellLen; cellIndex++ ) {
|
159
168
|
$t = $cells.eq( cellIndex );
|
160
|
-
col =
|
169
|
+
col = math.getCellIndex( $t );
|
161
170
|
if ( !$t.filter( '[' + mathAttr + ']' ).length && $.inArray( col, wo.math_ignore ) < 0 ) {
|
162
171
|
arry.push( math.processText( c, $t ) );
|
163
172
|
}
|
@@ -170,17 +179,48 @@
|
|
170
179
|
setColumnIndexes : function( c ) {
|
171
180
|
c.$table.after( '<div id="_tablesorter_table_placeholder"></div>' );
|
172
181
|
// detach table from DOM to speed up column indexing
|
173
|
-
var $table = c.$table.detach()
|
174
|
-
|
182
|
+
var $table = c.$table.detach(),
|
183
|
+
last = 1,
|
184
|
+
// only target rows with a colspan or rows included in a rowspan
|
185
|
+
$rows = $table.children( 'tbody' ).children().filter( function() {
|
186
|
+
var cells, indx, len,
|
187
|
+
$this = $( this ),
|
188
|
+
include = $this.children( '[colspan]' ).length > 0;
|
189
|
+
if ( last > 1 ) {
|
190
|
+
last--;
|
191
|
+
include = true;
|
192
|
+
} else if ( last < 1 ) {
|
193
|
+
last = 1;
|
194
|
+
}
|
195
|
+
if ( $this.children( '[rowspan]' ).length > 0 ) {
|
196
|
+
cells = this.cells;
|
197
|
+
// find max rowspan (in case more than one cell has a rowspan)
|
198
|
+
for ( indx = 0; indx < cells.length; indx++ ) {
|
199
|
+
last = Math.max( cells[ indx ].rowSpan, last );
|
200
|
+
}
|
201
|
+
}
|
202
|
+
return include;
|
203
|
+
});
|
204
|
+
// pass `c` (table.config) to computeColumnIndex so it won't add a data-column
|
205
|
+
// to every tbody cell, just the ones where the .cellIndex property doesn't match
|
206
|
+
// the calculated cell index - hopefully fixes the lag issue in #1048
|
207
|
+
ts.computeColumnIndex( $rows, c );
|
175
208
|
$( '#_tablesorter_table_placeholder' )
|
176
209
|
.after( $table )
|
177
210
|
.remove();
|
178
211
|
},
|
179
212
|
|
213
|
+
getCellIndex : function( $cell ) {
|
214
|
+
var indx = $cell.attr( 'data-column' );
|
215
|
+
return typeof indx === 'undefined' ? $cell[0].cellIndex : parseInt( indx, 10 );
|
216
|
+
},
|
217
|
+
|
180
218
|
recalculate : function(c, wo, init) {
|
181
219
|
if ( c && ( !wo.math_isUpdating || init ) ) {
|
182
220
|
|
183
|
-
var undef, time, mathAttr, $mathCells
|
221
|
+
var undef, time, mathAttr, $mathCells, indx, len,
|
222
|
+
changed = false,
|
223
|
+
filters = {};
|
184
224
|
if ( c.debug ) {
|
185
225
|
time = new Date();
|
186
226
|
}
|
@@ -196,7 +236,7 @@
|
|
196
236
|
// all non-info tbody cells
|
197
237
|
mathAttr = wo.math_dataAttrib;
|
198
238
|
$mathCells = c.$tbodies.children( 'tr' ).children( '[' + mathAttr + ']' );
|
199
|
-
math.mathType( c, $mathCells, wo.math_priority );
|
239
|
+
changed = math.mathType( c, $mathCells, wo.math_priority ) || changed;
|
200
240
|
|
201
241
|
// only info tbody cells
|
202
242
|
$mathCells = c.$table
|
@@ -207,20 +247,33 @@
|
|
207
247
|
|
208
248
|
// find the 'all' total
|
209
249
|
$mathCells = c.$table.children().children( 'tr' ).children( '[' + mathAttr + '^=all]' );
|
210
|
-
|
250
|
+
len = $mathCells.length;
|
251
|
+
// get math filter, if any
|
252
|
+
// hasFilter = $row.attr( mathAttr + '-filter' ) || wo.math_rowFilter;
|
253
|
+
$mathCells.each( function( indx, cell ) {
|
254
|
+
var $cell = $( cell ),
|
255
|
+
filter = $mathCells.eq( indx ).attr( mathAttr + '-filter' ) || wo.math_rowFilter;
|
256
|
+
filters[ filter ] = filters[ filter ] ? filters[ filter ].add( $cell ) : $cell;
|
257
|
+
});
|
258
|
+
$.each( filters, function( hasFilter, $cells ) {
|
259
|
+
changed = math.mathType( c, $cells, [ 'all' ], hasFilter ) || changed;
|
260
|
+
});
|
211
261
|
|
212
|
-
|
213
|
-
if (
|
214
|
-
|
215
|
-
|
262
|
+
// trigger an update only if cells inside the tbody changed
|
263
|
+
if ( changed ) {
|
264
|
+
wo.math_isUpdating = true;
|
265
|
+
if ( c.debug ) {
|
266
|
+
console[ console.group ? 'group' : 'log' ]( 'Math widget triggering an update after recalculation' );
|
267
|
+
}
|
216
268
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
269
|
+
// update internal cache
|
270
|
+
ts.update( c, undef, function(){
|
271
|
+
math.updateComplete( c );
|
272
|
+
});
|
221
273
|
|
222
|
-
|
223
|
-
|
274
|
+
if ( c.debug ) {
|
275
|
+
console.log( 'Math widget update completed' + ts.benchmark( time ) );
|
276
|
+
}
|
224
277
|
}
|
225
278
|
}
|
226
279
|
},
|
@@ -231,23 +284,25 @@
|
|
231
284
|
wo.math_isUpdating = false;
|
232
285
|
},
|
233
286
|
|
234
|
-
mathType : function( c, $cells, priority ) {
|
287
|
+
mathType : function( c, $cells, priority, hasFilter ) {
|
235
288
|
if ( $cells.length ) {
|
236
|
-
var
|
289
|
+
var getAll,
|
290
|
+
changed = false,
|
237
291
|
wo = c.widgetOptions,
|
238
292
|
mathAttr = wo.math_dataAttrib,
|
239
293
|
equations = ts.equations;
|
240
294
|
if ( priority[0] === 'all' ) {
|
241
|
-
//
|
242
|
-
getAll = math.getAll( c );
|
295
|
+
// mathType is called multiple times if more than one "hasFilter" is used
|
296
|
+
getAll = math.getAll( c, hasFilter );
|
243
297
|
}
|
244
298
|
if (c.debug) {
|
245
299
|
console[ console.group ? 'group' : 'log' ]( 'Tablesorter Math widget recalculation' );
|
246
300
|
}
|
247
301
|
// $.each is okay here... only 4 priorities
|
248
302
|
$.each( priority, function( i, type ) {
|
249
|
-
|
250
|
-
|
303
|
+
var index, arry, formula, result, $el,
|
304
|
+
$targetCells = $cells.filter( '[' + mathAttr + '^=' + type + ']' ),
|
305
|
+
len = $targetCells.length;
|
251
306
|
if ( len ) {
|
252
307
|
if (c.debug) {
|
253
308
|
console[ console.group ? 'group' : 'log' ]( type );
|
@@ -258,39 +313,58 @@
|
|
258
313
|
if ( $el.parent().hasClass( wo.filter_filteredRow || 'filtered' ) ) {
|
259
314
|
continue;
|
260
315
|
}
|
316
|
+
hasFilter = $el.attr( mathAttr + '-filter' ) || wo.math_rowFilter;
|
261
317
|
formula = ( $el.attr( mathAttr ) || '' ).replace( type + '-', '' );
|
262
|
-
arry = ( type === 'row' ) ? math.getRow( c, $el ) :
|
263
|
-
( type === 'all' ) ? getAll : math.getColumn( c, $el, type );
|
318
|
+
arry = ( type === 'row' ) ? math.getRow( c, $el, hasFilter ) :
|
319
|
+
( type === 'all' ) ? getAll : math.getColumn( c, $el, type, hasFilter );
|
264
320
|
if ( equations[ formula ] ) {
|
265
321
|
if ( arry.length ) {
|
266
322
|
result = equations[ formula ]( arry, c );
|
267
323
|
if ( c.debug ) {
|
268
|
-
console.log( $el.attr( mathAttr ), arry, '=', result );
|
324
|
+
console.log( $el.attr( mathAttr ), hasFilter ? '("' + hasFilter + '")' : '', arry, '=', result );
|
269
325
|
}
|
270
326
|
} else {
|
271
327
|
// mean will return a divide by zero error, everything else shows an undefined error
|
272
328
|
result = math.invalid( c, formula, formula === 'mean' ? 0 : 'undef' );
|
273
329
|
}
|
274
|
-
math.output( $el,
|
330
|
+
changed = math.output( $el, c, result, arry ) || changed;
|
275
331
|
}
|
276
332
|
}
|
277
333
|
if ( c.debug && console.groupEnd ) { console.groupEnd(); }
|
278
334
|
}
|
279
335
|
});
|
280
336
|
if ( c.debug && console.groupEnd ) { console.groupEnd(); }
|
337
|
+
return changed;
|
281
338
|
}
|
339
|
+
return false;
|
282
340
|
},
|
283
341
|
|
284
|
-
output : function( $cell,
|
342
|
+
output : function( $cell, c, value, arry ) {
|
285
343
|
// get mask from cell data-attribute: data-math-mask="#,##0.00"
|
286
|
-
var
|
344
|
+
var $el,
|
345
|
+
wo = c.widgetOptions,
|
346
|
+
changed = false,
|
347
|
+
prev = $cell.html(),
|
348
|
+
mask = $cell.attr( 'data-' + wo.math_data + '-mask' ) || wo.math_mask,
|
287
349
|
result = ts.formatMask( mask, value, wo.math_wrapPrefix, wo.math_wrapSuffix );
|
288
350
|
if ( typeof wo.math_complete === 'function' ) {
|
289
351
|
result = wo.math_complete( $cell, wo, result, value, arry );
|
290
352
|
}
|
291
353
|
if ( result !== false ) {
|
354
|
+
changed = prev !== result;
|
292
355
|
$cell.html( result );
|
293
356
|
}
|
357
|
+
// check if in a regular tbody, otherwise don't pass a changed flag
|
358
|
+
// to prevent unnecessary updating of the table cache
|
359
|
+
if ( changed ) {
|
360
|
+
$el = $cell.closest( 'tbody' );
|
361
|
+
// content was changed in a tfoot, info-only tbody or the resulting tbody is in a nested table
|
362
|
+
// then don't signal a change
|
363
|
+
if ( !$el.length || $el.hasClass( c.cssInfoBlock ) || $el.parent()[0] !== c.table ) {
|
364
|
+
return false;
|
365
|
+
}
|
366
|
+
}
|
367
|
+
return changed;
|
294
368
|
}
|
295
369
|
|
296
370
|
};
|
@@ -525,20 +599,24 @@
|
|
525
599
|
},
|
526
600
|
init : function( table, thisWidget, c, wo ) {
|
527
601
|
// filterEnd fires after updateComplete
|
528
|
-
var update = ts.hasWidget( table, 'filter' ) ? 'filterEnd' : 'updateComplete';
|
602
|
+
var update = ( ts.hasWidget( table, 'filter' ) ? 'filterEnd' : 'updateComplete' ) + '.tsmath';
|
603
|
+
// filterEnd is when the pager hides rows... so bind to pagerComplete
|
604
|
+
math.events += ( ts.hasWidget( table, 'pager' ) ? 'pagerComplete' : 'filterEnd' ) + '.tsmath ';
|
529
605
|
c.$table
|
530
|
-
.off( ( math.events + '
|
531
|
-
.on( math.events +
|
606
|
+
.off( ( math.events + 'updateComplete.tsmath ' + wo.math_event ).replace( /\s+/g, ' ' ) )
|
607
|
+
.on( math.events + wo.math_event, function( e ) {
|
608
|
+
if ( !this.hasInitialized ) { return; }
|
532
609
|
var init = e.type === 'tablesorter-initialized';
|
533
610
|
if ( !wo.math_isUpdating || init ) {
|
534
|
-
|
611
|
+
// don't setColumnIndexes on init here, or it gets done twice
|
612
|
+
if ( !/filter/.test( e.type ) && !init ) {
|
535
613
|
// redo data-column indexes on update
|
536
|
-
math.setColumnIndexes( c )
|
614
|
+
math.setColumnIndexes( c );
|
537
615
|
}
|
538
616
|
math.recalculate( c, wo, init );
|
539
617
|
}
|
540
618
|
})
|
541
|
-
.on( update
|
619
|
+
.on( update, function() {
|
542
620
|
setTimeout( function(){
|
543
621
|
math.updateComplete( c );
|
544
622
|
}, 40 );
|