jquery-tablesorter 1.19.4 → 1.20.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 +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 );
|