jquery-tablesorter 1.17.1 → 1.17.2
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 +6 -2
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +353 -228
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +41 -37
- data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +313 -192
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +2 -1
- data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-metric.js +63 -48
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +17 -12
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +10 -5
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +114 -71
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-output.js +95 -66
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +3 -2
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-repeatheaders.js +1 -1
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +120 -59
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +510 -242
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sortTbodies.js +228 -0
- data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +76 -59
- metadata +3 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! TableSorter (FORK) v2.22.
|
1
|
+
/*! TableSorter (FORK) v2.22.3 *//*
|
2
2
|
* Client-side table sorting with ease!
|
3
3
|
* @requires jQuery v1.2.6+
|
4
4
|
*
|
@@ -26,7 +26,7 @@
|
|
26
26
|
|
27
27
|
var ts = this;
|
28
28
|
|
29
|
-
ts.version = '2.22.
|
29
|
+
ts.version = '2.22.3';
|
30
30
|
|
31
31
|
ts.parsers = [];
|
32
32
|
ts.widgets = [];
|
@@ -191,10 +191,10 @@
|
|
191
191
|
if (typeof(t) === 'string') {
|
192
192
|
// check data-attribute first when set to 'basic'; don't use node.innerText - it's really slow!
|
193
193
|
// http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
);
|
194
|
+
if ( t === 'basic' && typeof ( te = $node.attr(c.textAttribute) ) !== 'undefined' ) {
|
195
|
+
return $.trim( te );
|
196
|
+
}
|
197
|
+
return $.trim( node.textContent || $node.text() );
|
198
198
|
} else {
|
199
199
|
if (typeof(t) === 'function') {
|
200
200
|
return $.trim( t($node[0], c.table, cellIndex) );
|
@@ -206,9 +206,8 @@
|
|
206
206
|
return $.trim( $node[0].textContent || $node.text() );
|
207
207
|
};
|
208
208
|
|
209
|
-
function detectParserForColumn(
|
209
|
+
function detectParserForColumn(c, rows, rowIndex, cellIndex) {
|
210
210
|
var cur, $node,
|
211
|
-
c = table.config,
|
212
211
|
i = ts.parsers.length,
|
213
212
|
node = false,
|
214
213
|
nodeValue = '',
|
@@ -219,7 +218,7 @@
|
|
219
218
|
node = rows[rowIndex].cells[cellIndex];
|
220
219
|
nodeValue = ts.getElementText(c, node, cellIndex);
|
221
220
|
$node = $(node);
|
222
|
-
if (
|
221
|
+
if (c.debug) {
|
223
222
|
log('Checking if value was empty on row ' + rowIndex + ', column: ' + cellIndex + ': "' + nodeValue + '"');
|
224
223
|
}
|
225
224
|
} else {
|
@@ -229,7 +228,7 @@
|
|
229
228
|
while (--i >= 0) {
|
230
229
|
cur = ts.parsers[i];
|
231
230
|
// ignore the default text parser because it will always be true
|
232
|
-
if (cur && cur.id !== 'text' && cur.is && cur.is(nodeValue, table, node, $node)) {
|
231
|
+
if (cur && cur.id !== 'text' && cur.is && cur.is(nodeValue, c.table, node, $node)) {
|
233
232
|
return cur;
|
234
233
|
}
|
235
234
|
}
|
@@ -238,7 +237,7 @@
|
|
238
237
|
}
|
239
238
|
|
240
239
|
// centralized function to extract/parse cell contents
|
241
|
-
function
|
240
|
+
ts.getParsedText = function( c, cell, colIndex, txt ) {
|
242
241
|
if ( typeof txt === 'undefined' ) {
|
243
242
|
txt = ts.getElementText( c, cell, colIndex );
|
244
243
|
}
|
@@ -261,16 +260,17 @@
|
|
261
260
|
}
|
262
261
|
}
|
263
262
|
return val;
|
264
|
-
}
|
263
|
+
};
|
265
264
|
|
266
|
-
function buildParserCache(
|
267
|
-
var
|
268
|
-
|
269
|
-
tb = c.$tbodies = c.$table.children('tbody:not(.' + c.cssInfoBlock + ')'),
|
270
|
-
rows, list, l, i, h, ch, np, p, e, time,
|
265
|
+
function buildParserCache( c, $tbodies ) {
|
266
|
+
var rows, list, l, i, h, ch, np, p, e, time, tb, len,
|
267
|
+
table = c.table,
|
271
268
|
j = 0,
|
272
|
-
parsersDebug = ''
|
273
|
-
|
269
|
+
parsersDebug = '';
|
270
|
+
// update table bodies in case we start with an empty table
|
271
|
+
c.$tbodies = c.$table.children('tbody:not(.' + c.cssInfoBlock + ')');
|
272
|
+
tb = typeof $tbodies === 'undefined' ? c.$tbodies : $tbodies;
|
273
|
+
len = tb.length;
|
274
274
|
if ( len === 0) {
|
275
275
|
return c.debug ? log('Warning: *Empty table!* Not building a parser cache') : '';
|
276
276
|
} else if (c.debug) {
|
@@ -305,7 +305,7 @@
|
|
305
305
|
e = false;
|
306
306
|
}
|
307
307
|
if (!p) {
|
308
|
-
p = detectParserForColumn(
|
308
|
+
p = detectParserForColumn(c, rows, -1, i);
|
309
309
|
}
|
310
310
|
if (c.debug) {
|
311
311
|
parsersDebug += 'column:' + i + '; extractor:' + e.id + '; parser:' + p.id + '; string:' + c.strings[i] + '; empty: ' + c.empties[i] + '\n';
|
@@ -325,12 +325,14 @@
|
|
325
325
|
}
|
326
326
|
|
327
327
|
/* utils */
|
328
|
-
function buildCache(table) {
|
329
|
-
var cc, t, v, i, j, k, $row, cols, cacheTime,
|
328
|
+
function buildCache(table, $tbodies) {
|
329
|
+
var cc, t, v, i, j, k, $tb, $row, cols, cacheTime,
|
330
330
|
totalRows, rowData, prevRowData, colMax,
|
331
331
|
c = table.config,
|
332
|
-
$tb = c.$tbodies,
|
333
332
|
parsers = c.parsers;
|
333
|
+
// update tbody variable
|
334
|
+
c.$tbodies = c.$table.children('tbody:not(.' + c.cssInfoBlock + ')');
|
335
|
+
$tb = typeof $tbodies === 'undefined' ? c.$tbodies : $tbodies,
|
334
336
|
c.cache = {};
|
335
337
|
c.totalRows = 0;
|
336
338
|
// if no parsers found, return - it's an empty table.
|
@@ -378,7 +380,7 @@
|
|
378
380
|
prevRowData.child[ t ] = [];
|
379
381
|
// child row content does not account for colspans/rowspans; so indexing may be off
|
380
382
|
for ( j = 0; j < c.columns; j++ ) {
|
381
|
-
prevRowData.child[ t ][ j ] = getParsedText( c, v[ j ], j );
|
383
|
+
prevRowData.child[ t ][ j ] = ts.getParsedText( c, v[ j ], j );
|
382
384
|
}
|
383
385
|
// go to the next for loop
|
384
386
|
continue;
|
@@ -394,7 +396,7 @@
|
|
394
396
|
}
|
395
397
|
t = ts.getElementText( c, $row[ 0 ].cells[j], j );
|
396
398
|
rowData.raw.push( t ); // save original row text
|
397
|
-
v = getParsedText( c, $row[ 0 ].cells[ j ], j, t );
|
399
|
+
v = ts.getParsedText( c, $row[ 0 ].cells[ j ], j, t );
|
398
400
|
cols.push( v );
|
399
401
|
if ( ( parsers[ j ].type || '' ).toLowerCase() === 'numeric' ) {
|
400
402
|
// determine column max value (ignore sign)
|
@@ -547,7 +549,7 @@
|
|
547
549
|
// remove rows/elements before update
|
548
550
|
c.$table.find(c.selectorRemove).remove();
|
549
551
|
// rebuild parsers
|
550
|
-
buildParserCache(
|
552
|
+
buildParserCache(c);
|
551
553
|
// rebuild the cache map
|
552
554
|
buildCache(table);
|
553
555
|
checkResort(c, resort, callback);
|
@@ -837,7 +839,7 @@
|
|
837
839
|
num = (c.strings[col]) ? c.string[c.strings[col]] || 0 : 0;
|
838
840
|
}
|
839
841
|
// fall back to built-in numeric sort
|
840
|
-
// var sort = $.tablesorter['sort' + s](
|
842
|
+
// var sort = $.tablesorter['sort' + s]( a[c], b[c], dir, colMax[c], table);
|
841
843
|
sort = c.numberSorter ? c.numberSorter(a[col], b[col], dir, colMax[col], table) :
|
842
844
|
ts[ 'sortNumeric' + (dir ? 'Asc' : 'Desc') ](a[col], b[col], num, colMax[col], col, table);
|
843
845
|
} else {
|
@@ -950,7 +952,7 @@
|
|
950
952
|
row = $tb.eq( tbdy ).find( 'tr' ).index( $row );
|
951
953
|
cache = tbcache.normalized[ row ];
|
952
954
|
icell = $cell.index();
|
953
|
-
t = getParsedText( c, cell, icell );
|
955
|
+
t = ts.getParsedText( c, cell, icell );
|
954
956
|
cache[ icell ] = t;
|
955
957
|
cache[ c.columns ].$row = $row;
|
956
958
|
if ( (c.parsers[icell].type || '').toLowerCase() === 'numeric' ) {
|
@@ -985,7 +987,7 @@
|
|
985
987
|
tbdy = c.$tbodies.index( $row.parents('tbody').filter(':first') );
|
986
988
|
// fixes adding rows to an empty table - see issue #179
|
987
989
|
if (!(c.parsers && c.parsers.length)) {
|
988
|
-
buildParserCache(
|
990
|
+
buildParserCache(c);
|
989
991
|
}
|
990
992
|
// add each row
|
991
993
|
for (i = 0; i < rows; i++) {
|
@@ -998,7 +1000,7 @@
|
|
998
1000
|
};
|
999
1001
|
// add each cell
|
1000
1002
|
for (j = 0; j < l; j++) {
|
1001
|
-
cells[j] = getParsedText( c, $row[i].cells[j], j );
|
1003
|
+
cells[j] = ts.getParsedText( c, $row[i].cells[j], j );
|
1002
1004
|
if ((c.parsers[j].type || '').toLowerCase() === 'numeric') {
|
1003
1005
|
// update column max value (ignore sign)
|
1004
1006
|
c.cache[tbdy].colMax[j] = Math.max(Math.abs(cells[j]) || 0, c.cache[tbdy].colMax[j] || 0);
|
@@ -1043,13 +1045,14 @@
|
|
1043
1045
|
callback(table);
|
1044
1046
|
}
|
1045
1047
|
})
|
1046
|
-
|
1048
|
+
// $tbodies variable is used by the tbody sorting widget
|
1049
|
+
.bind('updateCache' + c.namespace, function(e, callback, $tbodies){
|
1047
1050
|
// rebuild parsers
|
1048
1051
|
if (!(c.parsers && c.parsers.length)) {
|
1049
|
-
buildParserCache(
|
1052
|
+
buildParserCache(c, $tbodies);
|
1050
1053
|
}
|
1051
1054
|
// rebuild the cache map
|
1052
|
-
buildCache(table);
|
1055
|
+
buildCache(table, $tbodies);
|
1053
1056
|
if ($.isFunction(callback)) {
|
1054
1057
|
callback(table);
|
1055
1058
|
}
|
@@ -1169,7 +1172,7 @@
|
|
1169
1172
|
// add widget options before parsing (e.g. grouping widget has parser settings)
|
1170
1173
|
ts.applyWidgetOptions(table, c);
|
1171
1174
|
// try to auto detect column type, and store in tables config
|
1172
|
-
buildParserCache(
|
1175
|
+
buildParserCache(c);
|
1173
1176
|
// start total row count at zero
|
1174
1177
|
c.totalRows = 0;
|
1175
1178
|
// build the cache for the tbody cells
|
@@ -1395,10 +1398,11 @@
|
|
1395
1398
|
}
|
1396
1399
|
// ignore mouseup if mousedown wasn't on the same target
|
1397
1400
|
if ( type.match(' ' + c.pointerUp + ' ') && downTarget !== e.target && external !== true ) { return; }
|
1398
|
-
// set
|
1401
|
+
// set target on mousedown
|
1399
1402
|
if ( type.match(' ' + c.pointerDown + ' ') ) {
|
1400
1403
|
downTarget = e.target;
|
1401
|
-
// needed or jQuery v1.3.2
|
1404
|
+
// preventDefault needed or jQuery v1.3.2 and older throws an
|
1405
|
+
// "Uncaught TypeError: handler.apply is not a function" error
|
1402
1406
|
temp = $target.jquery.split( '.' );
|
1403
1407
|
if ( temp[0] === '1' && temp[1] < 4 ) { e.preventDefault(); }
|
1404
1408
|
return;
|
@@ -2137,7 +2141,7 @@
|
|
2137
2141
|
format: function(table, c, wo) {
|
2138
2142
|
var $tv, $tr, row, even, time, k, i, len,
|
2139
2143
|
child = new RegExp(c.cssChildRow, 'i'),
|
2140
|
-
b = c.$tbodies.add( $( c.namespace + '_extra_table' ).children( 'tbody' ) );
|
2144
|
+
b = c.$tbodies.add( $( c.namespace + '_extra_table' ).children( 'tbody:not(.' + c.cssInfoBlock + ')' ) );
|
2141
2145
|
if (c.debug) {
|
2142
2146
|
time = new Date();
|
2143
2147
|
}
|
@@ -4,7 +4,7 @@
|
|
4
4
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀▀▀▀██
|
5
5
|
█████▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██ ██ ▀████▀ █████▀ ██ ██ █████▀
|
6
6
|
*/
|
7
|
-
/*! tablesorter (FORK) - updated
|
7
|
+
/*! tablesorter (FORK) - updated 06-30-2015 (v2.22.2)*/
|
8
8
|
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
|
9
9
|
(function(factory) {
|
10
10
|
if (typeof define === 'function' && define.amd) {
|
@@ -476,6 +476,66 @@ ts.filter = {
|
|
476
476
|
// data.index = column index; table = table element ( DOM )
|
477
477
|
// data.parsed = array ( by column ) of boolean values ( from filter_useParsedData or 'filter-parsed' class )
|
478
478
|
types: {
|
479
|
+
or : function( c, data, vars ) {
|
480
|
+
if ( /\|/.test( data.iFilter ) || ts.filter.regex.orSplit.test( data.filter ) ) {
|
481
|
+
var indx, filterMatched, txt, query, regex,
|
482
|
+
// duplicate data but split filter
|
483
|
+
data2 = $.extend( {}, data ),
|
484
|
+
index = data.index,
|
485
|
+
parsed = data.parsed[ index ],
|
486
|
+
filter = data.filter.split( ts.filter.regex.orSplit ),
|
487
|
+
iFilter = data.iFilter.split( ts.filter.regex.orSplit ),
|
488
|
+
len = filter.length;
|
489
|
+
for ( indx = 0; indx < len; indx++ ) {
|
490
|
+
data2.nestedFilters = true;
|
491
|
+
data2.filter = '' + ( ts.filter.parseFilter( c, filter[ indx ], index, parsed ) || '' );
|
492
|
+
data2.iFilter = '' + ( ts.filter.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
|
493
|
+
query = '(' + ( ts.filter.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')';
|
494
|
+
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
495
|
+
// filterMatched = data2.filter === '' && indx > 0 ? true
|
496
|
+
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
497
|
+
filterMatched = regex.test( data2.exact ) || ts.filter.processTypes( c, data2, vars );
|
498
|
+
if ( filterMatched ) {
|
499
|
+
return filterMatched;
|
500
|
+
}
|
501
|
+
}
|
502
|
+
// may be null from processing types
|
503
|
+
return filterMatched || false;
|
504
|
+
}
|
505
|
+
return null;
|
506
|
+
},
|
507
|
+
// Look for an AND or && operator ( logical and )
|
508
|
+
and : function( c, data, vars ) {
|
509
|
+
if ( ts.filter.regex.andTest.test( data.filter ) ) {
|
510
|
+
var indx, filterMatched, result, txt, query, regex,
|
511
|
+
// duplicate data but split filter
|
512
|
+
data2 = $.extend( {}, data ),
|
513
|
+
index = data.index,
|
514
|
+
parsed = data.parsed[ index ],
|
515
|
+
filter = data.filter.split( ts.filter.regex.andSplit ),
|
516
|
+
iFilter = data.iFilter.split( ts.filter.regex.andSplit ),
|
517
|
+
len = filter.length;
|
518
|
+
for ( indx = 0; indx < len; indx++ ) {
|
519
|
+
data2.nestedFilters = true;
|
520
|
+
data2.filter = '' + ( ts.filter.parseFilter( c, filter[ indx ], index, parsed ) || '' );
|
521
|
+
data2.iFilter = '' + ( ts.filter.parseFilter( c, iFilter[ indx ], index, parsed ) || '' );
|
522
|
+
query = ( '(' + ( ts.filter.parseFilter( c, data2.filter, index, parsed ) || '' ) + ')' )
|
523
|
+
// replace wild cards since /(a*)/i will match anything
|
524
|
+
.replace( /\?/g, '\\S{1}' ).replace( /\*/g, '\\S*' );
|
525
|
+
regex = new RegExp( data.isMatch ? query : '^' + query + '$', c.widgetOptions.filter_ignoreCase ? 'i' : '' );
|
526
|
+
// look for an exact match with the 'and' unless the 'filter-match' class is found
|
527
|
+
result = ( regex.test( data2.exact ) || ts.filter.processTypes( c, data2, vars ) );
|
528
|
+
if ( indx === 0 ) {
|
529
|
+
filterMatched = result;
|
530
|
+
} else {
|
531
|
+
filterMatched = filterMatched && result;
|
532
|
+
}
|
533
|
+
}
|
534
|
+
// may be null from processing types
|
535
|
+
return filterMatched || false;
|
536
|
+
}
|
537
|
+
return null;
|
538
|
+
},
|
479
539
|
// Look for regex
|
480
540
|
regex: function( c, data ) {
|
481
541
|
if ( ts.filter.regex.regex.test( data.filter ) ) {
|
@@ -563,23 +623,6 @@ ts.filter = {
|
|
563
623
|
}
|
564
624
|
return null;
|
565
625
|
},
|
566
|
-
// Look for an AND or && operator ( logical and )
|
567
|
-
and : function( c, data ) {
|
568
|
-
if ( ts.filter.regex.andTest.test( data.filter ) ) {
|
569
|
-
var index = data.index,
|
570
|
-
parsed = data.parsed[index],
|
571
|
-
query = data.iFilter.split( ts.filter.regex.andSplit ),
|
572
|
-
result = data.iExact.search( $.trim( ts.filter.parseFilter( c, query[0], index, parsed ) ) ) >= 0,
|
573
|
-
indx = query.length - 1;
|
574
|
-
while ( result && indx ) {
|
575
|
-
result = result &&
|
576
|
-
data.iExact.search( $.trim( ts.filter.parseFilter( c, query[indx], index, parsed ) ) ) >= 0;
|
577
|
-
indx--;
|
578
|
-
}
|
579
|
-
return result;
|
580
|
-
}
|
581
|
-
return null;
|
582
|
-
},
|
583
626
|
// Look for a range ( using ' to ' or ' - ' ) - see issue #166; thanks matzhu!
|
584
627
|
range : function( c, data ) {
|
585
628
|
if ( ts.filter.regex.toTest.test( data.iFilter ) ) {
|
@@ -616,24 +659,20 @@ ts.filter = {
|
|
616
659
|
},
|
617
660
|
// Look for wild card: ? = single, * = multiple, or | = logical OR
|
618
661
|
wild : function( c, data ) {
|
619
|
-
if ( /[\?\*\|]/.test( data.iFilter )
|
662
|
+
if ( /[\?\*\|]/.test( data.iFilter ) ) {
|
620
663
|
var index = data.index,
|
621
664
|
parsed = data.parsed[ index ],
|
622
|
-
|
623
|
-
query = '' + ( ts.filter.parseFilter( c, txt, index, parsed ) || '' );
|
665
|
+
query = '' + ( ts.filter.parseFilter( c, data.iFilter, index, parsed ) || '' );
|
624
666
|
// look for an exact match with the 'or' unless the 'filter-match' class is found
|
625
|
-
if (
|
626
|
-
|
627
|
-
if ( query[ query.length - 1 ] === '|' ) {
|
628
|
-
query += '*';
|
629
|
-
}
|
630
|
-
query = data.anyMatch && $.isArray( data.rowArray ) ?
|
631
|
-
'(' + query + ')' :
|
632
|
-
'^(' + query + ')$';
|
667
|
+
if ( !/\?\*/.test( query ) && data.nestedFilters ) {
|
668
|
+
query = data.isMatch ? query : '^(' + query + ')$';
|
633
669
|
}
|
634
670
|
// parsing the filter may not work properly when using wildcards =/
|
635
|
-
return new RegExp(
|
636
|
-
.
|
671
|
+
return new RegExp(
|
672
|
+
query.replace( /\?/g, '\\S{1}' ).replace( /\*/g, '\\S*' ),
|
673
|
+
c.widgetOptions.filter_ignoreCase ? 'i' : ''
|
674
|
+
)
|
675
|
+
.test( data.exact );
|
637
676
|
}
|
638
677
|
return null;
|
639
678
|
},
|
@@ -687,7 +726,7 @@ ts.filter = {
|
|
687
726
|
toSplit : new RegExp( '(?:\\s+(?:-|' + ts.language.to + ')\\s+)' ,'gi' ),
|
688
727
|
andTest : new RegExp( '\\s+(' + ts.language.and + '|&&)\\s+', 'i' ),
|
689
728
|
andSplit : new RegExp( '(?:\\s+(?:' + ts.language.and + '|&&)\\s+)', 'gi' ),
|
690
|
-
|
729
|
+
orSplit : new RegExp( '(?:\\s+(?:' + ts.language.or + ')\\s+|\\|)', 'gi' ),
|
691
730
|
iQuery : new RegExp( val, 'i' ),
|
692
731
|
igQuery : new RegExp( val, 'ig' )
|
693
732
|
});
|
@@ -907,7 +946,6 @@ ts.filter = {
|
|
907
946
|
}
|
908
947
|
}
|
909
948
|
},
|
910
|
-
|
911
949
|
setDefaults: function( table, c, wo ) {
|
912
950
|
var isArray, saved, indx, col, $filters,
|
913
951
|
// get current ( default ) filters
|
@@ -1134,14 +1172,13 @@ ts.filter = {
|
|
1134
1172
|
}
|
1135
1173
|
},
|
1136
1174
|
hideFilters: function( table, c ) {
|
1137
|
-
var
|
1138
|
-
|
1175
|
+
var timer;
|
1176
|
+
c.$table
|
1139
1177
|
.find( '.' + tscss.filterRow )
|
1140
|
-
.addClass( tscss.filterRowHide )
|
1141
1178
|
.bind( 'mouseenter mouseleave', function( e ) {
|
1142
1179
|
// save event object - http://bugs.jquery.com/ticket/12140
|
1143
|
-
var event = e
|
1144
|
-
|
1180
|
+
var event = e,
|
1181
|
+
$filterRow = $( this );
|
1145
1182
|
clearTimeout( timer );
|
1146
1183
|
timer = setTimeout( function() {
|
1147
1184
|
if ( /enter|over/.test( event.type ) ) {
|
@@ -1159,13 +1196,14 @@ ts.filter = {
|
|
1159
1196
|
}, 200 );
|
1160
1197
|
})
|
1161
1198
|
.find( 'input, select' ).bind( 'focus blur', function( e ) {
|
1162
|
-
|
1199
|
+
var event = e,
|
1200
|
+
$row = $( this ).closest( 'tr' );
|
1163
1201
|
clearTimeout( timer );
|
1164
|
-
var event = e;
|
1165
1202
|
timer = setTimeout( function() {
|
1203
|
+
clearTimeout( timer );
|
1166
1204
|
// don't hide row if any filter has a value
|
1167
1205
|
if ( ts.getFilters( c.$table ).join( '' ) === '' ) {
|
1168
|
-
$
|
1206
|
+
$row.toggleClass( tscss.filterRowHide, event.type !== 'focus' );
|
1169
1207
|
}
|
1170
1208
|
}, 200 );
|
1171
1209
|
});
|
@@ -1199,7 +1237,7 @@ ts.filter = {
|
|
1199
1237
|
return $( b ).attr( 'data-lastSearchTime' ) - $( a ).attr( 'data-lastSearchTime' );
|
1200
1238
|
});
|
1201
1239
|
}
|
1202
|
-
return $();
|
1240
|
+
return $input || $();
|
1203
1241
|
},
|
1204
1242
|
multipleColumns: function( c, $input ) {
|
1205
1243
|
// look for multiple columns '1-3,4-6,8' in data-column
|
@@ -1252,8 +1290,22 @@ ts.filter = {
|
|
1252
1290
|
}
|
1253
1291
|
return columns;
|
1254
1292
|
},
|
1293
|
+
processTypes: function( c, data, vars ) {
|
1294
|
+
var ffxn,
|
1295
|
+
filterMatched = null,
|
1296
|
+
matches = null;
|
1297
|
+
for ( ffxn in ts.filter.types ) {
|
1298
|
+
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
|
1299
|
+
matches = ts.filter.types[ffxn]( c, data, vars );
|
1300
|
+
if ( matches !== null ) {
|
1301
|
+
filterMatched = matches;
|
1302
|
+
}
|
1303
|
+
}
|
1304
|
+
}
|
1305
|
+
return filterMatched;
|
1306
|
+
},
|
1255
1307
|
processRow: function( c, data, vars ) {
|
1256
|
-
var
|
1308
|
+
var columnIndex, hasSelect, result, val, filterMatched,
|
1257
1309
|
fxn, ffxn, txt,
|
1258
1310
|
regex = ts.filter.regex,
|
1259
1311
|
wo = c.widgetOptions,
|
@@ -1264,6 +1316,7 @@ ts.filter = {
|
|
1264
1316
|
// look for multiple columns '1-3,4-6,8'
|
1265
1317
|
columnIndex = ts.filter.multipleColumns( c, wo.filter_$anyMatch );
|
1266
1318
|
data.anyMatch = true;
|
1319
|
+
data.isMatch = true;
|
1267
1320
|
data.rowArray = data.$cells.map( function( i ) {
|
1268
1321
|
if ( $.inArray( i, columnIndex ) > -1 ) {
|
1269
1322
|
if ( data.parsed[ i ] ) {
|
@@ -1283,16 +1336,10 @@ ts.filter = {
|
|
1283
1336
|
data.exact = data.rowArray.join( ' ' );
|
1284
1337
|
data.iExact = wo.filter_ignoreCase ? data.exact.toLowerCase() : data.exact;
|
1285
1338
|
data.cache = data.cacheArray.slice( 0, -1 ).join( ' ' );
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
matches = ts.filter.types[ffxn]( c, data );
|
1291
|
-
if ( matches !== null ) {
|
1292
|
-
filterMatched = matches;
|
1293
|
-
}
|
1294
|
-
}
|
1295
|
-
}
|
1339
|
+
|
1340
|
+
vars.excludeMatch = vars.noAnyMatch;
|
1341
|
+
filterMatched = ts.filter.processTypes( c, data, vars );
|
1342
|
+
|
1296
1343
|
if ( filterMatched !== null ) {
|
1297
1344
|
showRow = filterMatched;
|
1298
1345
|
} else {
|
@@ -1319,7 +1366,7 @@ ts.filter = {
|
|
1319
1366
|
data.index = columnIndex;
|
1320
1367
|
|
1321
1368
|
// filter types to exclude, per column
|
1322
|
-
excludeMatch = vars.excludeFilter[ columnIndex ];
|
1369
|
+
vars.excludeMatch = vars.excludeFilter[ columnIndex ];
|
1323
1370
|
|
1324
1371
|
// ignore if filter is empty or disabled
|
1325
1372
|
if ( data.filter ) {
|
@@ -1333,6 +1380,9 @@ ts.filter = {
|
|
1333
1380
|
}
|
1334
1381
|
data.iExact = !regex.type.test( typeof data.exact ) && wo.filter_ignoreCase ?
|
1335
1382
|
data.exact.toLowerCase() : data.exact;
|
1383
|
+
|
1384
|
+
data.isMatch = c.$headerIndexed[ data.index ].hasClass( 'filter-match' );
|
1385
|
+
|
1336
1386
|
result = showRow; // if showRow is true, show that row
|
1337
1387
|
|
1338
1388
|
// in case select filter option has a different value vs text 'a - z|A through Z'
|
@@ -1357,13 +1407,12 @@ ts.filter = {
|
|
1357
1407
|
// data.filter = case sensitive
|
1358
1408
|
data.iFilter = wo.filter_ignoreCase ? ( data.filter || '' ).toLowerCase() : data.filter;
|
1359
1409
|
fxn = vars.functions[ columnIndex ];
|
1360
|
-
|
1361
|
-
hasSelect = $cell.hasClass( 'filter-select' );
|
1410
|
+
hasSelect = c.$headerIndexed[ columnIndex ].hasClass( 'filter-select' );
|
1362
1411
|
filterMatched = null;
|
1363
1412
|
if ( fxn || ( hasSelect && val ) ) {
|
1364
1413
|
if ( fxn === true || hasSelect ) {
|
1365
1414
|
// default selector uses exact match unless 'filter-match' class is found
|
1366
|
-
filterMatched =
|
1415
|
+
filterMatched = data.isMatch ?
|
1367
1416
|
data.iExact.search( data.iFilter ) >= 0 :
|
1368
1417
|
data.filter === data.exact;
|
1369
1418
|
} else if ( typeof fxn === 'function' ) {
|
@@ -1380,15 +1429,7 @@ ts.filter = {
|
|
1380
1429
|
if ( filterMatched === null ) {
|
1381
1430
|
// cycle through the different filters
|
1382
1431
|
// filters return a boolean or null if nothing matches
|
1383
|
-
|
1384
|
-
for ( ffxn in ts.filter.types ) {
|
1385
|
-
if ( $.inArray( ffxn, excludeMatch ) < 0 && matches === null ) {
|
1386
|
-
matches = ts.filter.types[ ffxn ]( c, data );
|
1387
|
-
if ( matches !== null ) {
|
1388
|
-
filterMatched = matches;
|
1389
|
-
}
|
1390
|
-
}
|
1391
|
-
}
|
1432
|
+
filterMatched = ts.filter.processTypes( c, data, vars );
|
1392
1433
|
if ( filterMatched !== null ) {
|
1393
1434
|
result = filterMatched;
|
1394
1435
|
// Look for match, and add child row data for matching
|
@@ -1422,7 +1463,7 @@ ts.filter = {
|
|
1422
1463
|
anyMatch: false,
|
1423
1464
|
filters: filters,
|
1424
1465
|
// regex filter type cache
|
1425
|
-
filter_regexCache : []
|
1466
|
+
filter_regexCache : []
|
1426
1467
|
},
|
1427
1468
|
vars = {
|
1428
1469
|
// anyMatch really screws up with these types of filters
|
@@ -1643,7 +1684,7 @@ ts.filter = {
|
|
1643
1684
|
},
|
1644
1685
|
getOptionSource: function( table, column, onlyAvail ) {
|
1645
1686
|
table = $( table )[0];
|
1646
|
-
var cts, indx, len,
|
1687
|
+
var cts, txt, indx, len,
|
1647
1688
|
c = table.config,
|
1648
1689
|
wo = c.widgetOptions,
|
1649
1690
|
parsed = [],
|
@@ -1688,11 +1729,13 @@ ts.filter = {
|
|
1688
1729
|
len = arry.length;
|
1689
1730
|
// parse select option values
|
1690
1731
|
for ( indx = 0; indx < len; indx++ ) {
|
1732
|
+
txt = arry[ indx ];
|
1691
1733
|
// parse array data using set column parser; this DOES NOT pass the original
|
1692
1734
|
// table cell to the parser format function
|
1693
1735
|
parsed.push({
|
1694
|
-
t :
|
1695
|
-
|
1736
|
+
t : txt,
|
1737
|
+
// check parser length - fixes #934
|
1738
|
+
p : c.parsers && c.parsers.length && c.parsers[ column ].format( txt, table, [], column ) || txt
|
1696
1739
|
});
|
1697
1740
|
}
|
1698
1741
|
|
@@ -1882,8 +1925,8 @@ ts.getFilters = function( table, getRaw, setFilters, skipFirst ) {
|
|
1882
1925
|
$column = ts.filter.getLatestSearch( $column );
|
1883
1926
|
if ( $.isArray( setFilters ) ) {
|
1884
1927
|
// skip first ( latest input ) to maintain cursor position while typing
|
1885
|
-
if ( skipFirst ) {
|
1886
|
-
$column.slice( 1 );
|
1928
|
+
if ( skipFirst && $column.length > 1 ) {
|
1929
|
+
$column = $column.slice( 1 );
|
1887
1930
|
}
|
1888
1931
|
if ( i === c.columns ) {
|
1889
1932
|
// prevent data-column='all' from filling data-column='0,1' ( etc )
|
@@ -1955,32 +1998,34 @@ $.extend(ts.css, {
|
|
1955
1998
|
// Add a resize event to table headers
|
1956
1999
|
ts.addHeaderResizeEvent = function(table, disable, settings) {
|
1957
2000
|
table = $(table)[0]; // make sure we're using a dom element
|
1958
|
-
|
1959
|
-
|
2001
|
+
if ( !table.config ) { return; }
|
2002
|
+
var defaults = {
|
1960
2003
|
timer : 250
|
1961
2004
|
},
|
1962
2005
|
options = $.extend({}, defaults, settings),
|
1963
2006
|
c = table.config,
|
1964
2007
|
wo = c.widgetOptions,
|
1965
|
-
checkSizes = function(triggerEvent) {
|
2008
|
+
checkSizes = function( triggerEvent ) {
|
2009
|
+
var index, headers, $header, sizes, width, height,
|
2010
|
+
len = c.$headers.length;
|
1966
2011
|
wo.resize_flag = true;
|
1967
2012
|
headers = [];
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
if (width !== sizes[0] || height !== sizes[1]) {
|
1974
|
-
$header.data('savedSizes', [ width, height ]);
|
1975
|
-
headers.push(
|
2013
|
+
for ( index = 0; index < len; index++ ) {
|
2014
|
+
$header = c.$headers.eq( index );
|
2015
|
+
sizes = $header.data( 'savedSizes' ) || [ 0,0 ]; // fixes #394
|
2016
|
+
width = $header[0].offsetWidth;
|
2017
|
+
height = $header[0].offsetHeight;
|
2018
|
+
if ( width !== sizes[0] || height !== sizes[1] ) {
|
2019
|
+
$header.data( 'savedSizes', [ width, height ] );
|
2020
|
+
headers.push( $header[0] );
|
1976
2021
|
}
|
1977
|
-
}
|
1978
|
-
if (headers.length && triggerEvent !== false) {
|
1979
|
-
c.$table.trigger('resize', [ headers ]);
|
2022
|
+
}
|
2023
|
+
if ( headers.length && triggerEvent !== false ) {
|
2024
|
+
c.$table.trigger( 'resize', [ headers ] );
|
1980
2025
|
}
|
1981
2026
|
wo.resize_flag = false;
|
1982
2027
|
};
|
1983
|
-
checkSizes(false);
|
2028
|
+
checkSizes( false );
|
1984
2029
|
clearInterval(wo.resize_timer);
|
1985
2030
|
if (disable) {
|
1986
2031
|
wo.resize_flag = false;
|
@@ -2016,7 +2061,8 @@ ts.addWidget({
|
|
2016
2061
|
if ( c.$table.hasClass('hasStickyHeaders') || ($.inArray('filter', c.widgets) >= 0 && !c.$table.hasClass('hasFilters')) ) {
|
2017
2062
|
return;
|
2018
2063
|
}
|
2019
|
-
var
|
2064
|
+
var index, len, $t,
|
2065
|
+
$table = c.$table,
|
2020
2066
|
// add position: relative to attach element, hopefully it won't cause trouble.
|
2021
2067
|
$attach = $(wo.stickyHeaders_attachTo),
|
2022
2068
|
namespace = c.namespace + 'stickyheaders ',
|
@@ -2051,17 +2097,19 @@ ts.addWidget({
|
|
2051
2097
|
laststate = '',
|
2052
2098
|
spacing = 0,
|
2053
2099
|
setWidth = function($orig, $clone){
|
2054
|
-
$
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2100
|
+
var index, width, border, $cell, $this,
|
2101
|
+
$cells = $orig.filter(':visible'),
|
2102
|
+
len = $cells.length;
|
2103
|
+
for ( index = 0; index < len; index++ ) {
|
2104
|
+
$cell = $clone.filter(':visible').eq(index);
|
2105
|
+
$this = $cells.eq(index);
|
2058
2106
|
// code from https://github.com/jmosbech/StickyTableHeaders
|
2059
2107
|
if ($this.css('box-sizing') === 'border-box') {
|
2060
2108
|
width = $this.outerWidth();
|
2061
2109
|
} else {
|
2062
2110
|
if ($cell.css('border-collapse') === 'collapse') {
|
2063
2111
|
if (window.getComputedStyle) {
|
2064
|
-
width = parseFloat( window.getComputedStyle(this, null).width );
|
2112
|
+
width = parseFloat( window.getComputedStyle($this[0], null).width );
|
2065
2113
|
} else {
|
2066
2114
|
// ie8 only
|
2067
2115
|
border = parseFloat( $this.css('border-width') );
|
@@ -2072,10 +2120,11 @@ ts.addWidget({
|
|
2072
2120
|
}
|
2073
2121
|
}
|
2074
2122
|
$cell.css({
|
2123
|
+
'width': width,
|
2075
2124
|
'min-width': width,
|
2076
2125
|
'max-width': width
|
2077
2126
|
});
|
2078
|
-
}
|
2127
|
+
}
|
2079
2128
|
},
|
2080
2129
|
resizeHeader = function() {
|
2081
2130
|
stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0;
|
@@ -2087,6 +2136,39 @@ ts.addWidget({
|
|
2087
2136
|
});
|
2088
2137
|
setWidth( $table, $stickyTable );
|
2089
2138
|
setWidth( $header, $stickyCells );
|
2139
|
+
},
|
2140
|
+
scrollSticky = function( resizing ) {
|
2141
|
+
if (!$table.is(':visible')) { return; } // fixes #278
|
2142
|
+
// Detect nested tables - fixes #724
|
2143
|
+
nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
|
2144
|
+
var offset = $table.offset(),
|
2145
|
+
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
|
2146
|
+
xWindow = $.isWindow( $xScroll[0] ),
|
2147
|
+
// scrollTop = ( $attach.length ? $attach.offset().top : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
|
2148
|
+
scrollTop = ( $attach.length ? ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
|
2149
|
+
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)),
|
2150
|
+
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
|
2151
|
+
cssSettings = { visibility : isVisible };
|
2152
|
+
|
2153
|
+
if ($attach.length) {
|
2154
|
+
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
|
2155
|
+
}
|
2156
|
+
if (xWindow) {
|
2157
|
+
// adjust when scrolling horizontally - fixes issue #143
|
2158
|
+
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing;
|
2159
|
+
}
|
2160
|
+
if ($nestedSticky.length) {
|
2161
|
+
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
|
2162
|
+
}
|
2163
|
+
$stickyWrap
|
2164
|
+
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
|
2165
|
+
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
|
2166
|
+
.css(cssSettings);
|
2167
|
+
if (isVisible !== laststate || resizing) {
|
2168
|
+
// make sure the column widths match
|
2169
|
+
resizeHeader();
|
2170
|
+
laststate = isVisible;
|
2171
|
+
}
|
2090
2172
|
};
|
2091
2173
|
// only add a position relative if a position isn't already defined
|
2092
2174
|
if ($attach.length && !$attach.css('position')) {
|
@@ -2118,48 +2200,26 @@ ts.addWidget({
|
|
2118
2200
|
|
2119
2201
|
// onRenderHeader is defined, we need to do something about it (fixes #641)
|
2120
2202
|
if (c.onRenderHeader) {
|
2121
|
-
$stickyThead.children('tr').children()
|
2203
|
+
$t = $stickyThead.children('tr').children();
|
2204
|
+
len = $t.length;
|
2205
|
+
for ( index = 0; index < len; index++ ) {
|
2122
2206
|
// send second parameter
|
2123
|
-
c.onRenderHeader.apply( $(
|
2124
|
-
}
|
2207
|
+
c.onRenderHeader.apply( $t.eq( index ), [ index, c, $stickyTable ] );
|
2208
|
+
}
|
2125
2209
|
}
|
2126
2210
|
|
2127
2211
|
// make it sticky!
|
2128
2212
|
$xScroll.add($yScroll)
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)),
|
2140
|
-
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
|
2141
|
-
cssSettings = { visibility : isVisible };
|
2142
|
-
|
2143
|
-
if ($attach.length) {
|
2144
|
-
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
|
2145
|
-
}
|
2146
|
-
if (xWindow) {
|
2147
|
-
// adjust when scrolling horizontally - fixes issue #143
|
2148
|
-
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing;
|
2149
|
-
}
|
2150
|
-
if ($nestedSticky.length) {
|
2151
|
-
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
|
2152
|
-
}
|
2153
|
-
$stickyWrap
|
2154
|
-
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
|
2155
|
-
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
|
2156
|
-
.css(cssSettings);
|
2157
|
-
if (isVisible !== laststate || event.type === 'resize') {
|
2158
|
-
// make sure the column widths match
|
2159
|
-
resizeHeader();
|
2160
|
-
laststate = isVisible;
|
2161
|
-
}
|
2162
|
-
});
|
2213
|
+
.unbind( ('scroll resize '.split(' ').join( namespace )).replace(/\s+/g, ' ') )
|
2214
|
+
.bind('scroll resize '.split(' ').join( namespace ), function( event ) {
|
2215
|
+
scrollSticky( event.type === 'resize' );
|
2216
|
+
});
|
2217
|
+
c.$table
|
2218
|
+
.unbind('stickyHeadersUpdate' + namespace)
|
2219
|
+
.bind('stickyHeadersUpdate' + namespace, function(){
|
2220
|
+
scrollSticky( true );
|
2221
|
+
});
|
2222
|
+
|
2163
2223
|
if (wo.stickyHeaders_addResizeEvent) {
|
2164
2224
|
ts.addHeaderResizeEvent(table);
|
2165
2225
|
}
|
@@ -2195,7 +2255,7 @@ ts.addWidget({
|
|
2195
2255
|
var namespace = c.namespace + 'stickyheaders ';
|
2196
2256
|
c.$table
|
2197
2257
|
.removeClass('hasStickyHeaders')
|
2198
|
-
.unbind( ('pagerComplete filterEnd '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
|
2258
|
+
.unbind( ('pagerComplete filterEnd stickyHeadersUpdate '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
|
2199
2259
|
.next('.' + ts.css.stickyWrap).remove();
|
2200
2260
|
if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
|
2201
2261
|
$(window)
|
@@ -2209,7 +2269,8 @@ ts.addWidget({
|
|
2209
2269
|
|
2210
2270
|
})(jQuery, window);
|
2211
2271
|
|
2212
|
-
/*! Widget: resizable - updated
|
2272
|
+
/*! Widget: resizable - updated 6/26/2015 (v2.22.2) */
|
2273
|
+
/*jshint browser:true, jquery:true, unused:false */
|
2213
2274
|
;(function ($, window) {
|
2214
2275
|
'use strict';
|
2215
2276
|
var ts = $.tablesorter || {};
|
@@ -2228,8 +2289,8 @@ $(function(){
|
|
2228
2289
|
'-khtml-user-select: none; -webkit-user-select: none; user-select: none; }' +
|
2229
2290
|
'.' + ts.css.resizableContainer + ' { position: relative; height: 1px; }' +
|
2230
2291
|
// make handle z-index > than stickyHeader z-index, so the handle stays above sticky header
|
2231
|
-
'.' + ts.css.resizableHandle + ' { position: absolute; display: inline-block; width: 8px;
|
2232
|
-
'cursor: ew-resize; z-index: 3; user-select: none; -moz-user-select: none; }' +
|
2292
|
+
'.' + ts.css.resizableHandle + ' { position: absolute; display: inline-block; width: 8px;' +
|
2293
|
+
'top: 1px; cursor: ew-resize; z-index: 3; user-select: none; -moz-user-select: none; }' +
|
2233
2294
|
'</style>';
|
2234
2295
|
$(s).appendTo('body');
|
2235
2296
|
});
|
@@ -2238,34 +2299,69 @@ ts.resizable = {
|
|
2238
2299
|
init : function( c, wo ) {
|
2239
2300
|
if ( c.$table.hasClass( 'hasResizable' ) ) { return; }
|
2240
2301
|
c.$table.addClass( 'hasResizable' );
|
2241
|
-
|
2302
|
+
|
2303
|
+
var noResize, $header, column, storedSizes, tmp,
|
2304
|
+
$table = c.$table,
|
2305
|
+
$parent = $table.parent(),
|
2306
|
+
marginTop = parseInt( $table.css( 'margin-top' ), 10 ),
|
2242
2307
|
|
2243
2308
|
// internal variables
|
2244
|
-
wo.resizable_ = {
|
2245
|
-
|
2309
|
+
vars = wo.resizable_ = {
|
2310
|
+
useStorage : ts.storage && wo.resizable !== false,
|
2311
|
+
$wrap : $parent,
|
2246
2312
|
mouseXPosition : 0,
|
2247
2313
|
$target : null,
|
2248
2314
|
$next : null,
|
2249
|
-
overflow :
|
2250
|
-
|
2315
|
+
overflow : $parent.css('overflow') === 'auto' ||
|
2316
|
+
$parent.css('overflow') === 'scroll' ||
|
2317
|
+
$parent.css('overflow-x') === 'auto' ||
|
2318
|
+
$parent.css('overflow-x') === 'scroll',
|
2251
2319
|
storedSizes : []
|
2252
2320
|
};
|
2253
2321
|
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2322
|
+
// set default widths
|
2323
|
+
ts.resizableReset( c.table, true );
|
2324
|
+
|
2325
|
+
// now get measurements!
|
2326
|
+
vars.tableWidth = $table.width();
|
2327
|
+
// attempt to autodetect
|
2328
|
+
vars.fullWidth = Math.abs( $parent.width() - vars.tableWidth ) < 20;
|
2329
|
+
|
2330
|
+
/*
|
2331
|
+
// Hacky method to determine if table width is set to "auto"
|
2332
|
+
// http://stackoverflow.com/a/20892048/145346
|
2333
|
+
if ( !vars.fullWidth ) {
|
2334
|
+
tmp = $table.width();
|
2335
|
+
$header = $table.wrap('<span>').parent(); // temp variable
|
2336
|
+
storedSizes = parseInt( $table.css( 'margin-left' ), 10 ) || 0;
|
2337
|
+
$table.css( 'margin-left', storedSizes + 50 );
|
2338
|
+
vars.tableWidth = $header.width() > tmp ? 'auto' : tmp;
|
2339
|
+
$table.css( 'margin-left', storedSizes ? storedSizes : '' );
|
2340
|
+
$header = null;
|
2341
|
+
$table.unwrap('<span>');
|
2342
|
+
}
|
2343
|
+
*/
|
2344
|
+
|
2345
|
+
if ( vars.useStorage && vars.overflow ) {
|
2346
|
+
// save table width
|
2347
|
+
ts.storage( c.table, 'tablesorter-table-original-css-width', vars.tableWidth );
|
2348
|
+
tmp = ts.storage( c.table, 'tablesorter-table-resized-width' ) || 'auto';
|
2349
|
+
ts.resizable.setWidth( $table, tmp, true );
|
2350
|
+
}
|
2351
|
+
wo.resizable_.storedSizes = storedSizes = ( vars.useStorage ?
|
2258
2352
|
ts.storage( c.table, ts.css.resizableStorage ) :
|
2259
2353
|
[] ) || [];
|
2260
2354
|
ts.resizable.setWidths( c, wo, storedSizes );
|
2355
|
+
ts.resizable.updateStoredSizes( c, wo );
|
2261
2356
|
|
2262
2357
|
wo.$resizable_container = $( '<div class="' + ts.css.resizableContainer + '">' )
|
2263
2358
|
.css({ top : marginTop })
|
2264
|
-
.insertBefore(
|
2359
|
+
.insertBefore( $table );
|
2265
2360
|
// add container
|
2266
2361
|
for ( column = 0; column < c.columns; column++ ) {
|
2267
2362
|
$header = c.$headerIndexed[ column ];
|
2268
|
-
|
2363
|
+
tmp = ts.getColumnData( c.table, c.headers, column );
|
2364
|
+
noResize = ts.getData( $header, tmp, 'resizable' ) === 'false';
|
2269
2365
|
if ( !noResize ) {
|
2270
2366
|
$( '<div class="' + ts.css.resizableHandle + '">' )
|
2271
2367
|
.appendTo( wo.$resizable_container )
|
@@ -2277,37 +2373,52 @@ ts.resizable = {
|
|
2277
2373
|
.bind( 'selectstart', false );
|
2278
2374
|
}
|
2279
2375
|
}
|
2280
|
-
|
2376
|
+
$table.one('tablesorter-initialized', function() {
|
2281
2377
|
ts.resizable.setHandlePosition( c, wo );
|
2282
2378
|
ts.resizable.bindings( this.config, this.config.widgetOptions );
|
2283
2379
|
});
|
2284
2380
|
},
|
2285
2381
|
|
2286
|
-
|
2382
|
+
updateStoredSizes : function( c, wo ) {
|
2383
|
+
var column, $header,
|
2384
|
+
len = c.columns,
|
2385
|
+
vars = wo.resizable_;
|
2386
|
+
vars.storedSizes = [];
|
2387
|
+
for ( column = 0; column < len; column++ ) {
|
2388
|
+
$header = c.$headerIndexed[ column ];
|
2389
|
+
vars.storedSizes[ column ] = $header.is(':visible') ? $header.width() : 0;
|
2390
|
+
}
|
2391
|
+
},
|
2392
|
+
|
2393
|
+
setWidth : function( $el, width, overflow ) {
|
2394
|
+
// overflow tables need min & max width set as well
|
2287
2395
|
$el.css({
|
2288
2396
|
'width' : width,
|
2289
|
-
'min-width' : '',
|
2290
|
-
'max-width' : ''
|
2397
|
+
'min-width' : overflow ? width : '',
|
2398
|
+
'max-width' : overflow ? width : ''
|
2291
2399
|
});
|
2292
2400
|
},
|
2293
2401
|
|
2294
2402
|
setWidths : function( c, wo, storedSizes ) {
|
2295
|
-
var column,
|
2403
|
+
var column, $temp,
|
2404
|
+
vars = wo.resizable_,
|
2296
2405
|
$extra = $( c.namespace + '_extra_headers' ),
|
2297
2406
|
$col = c.$table.children( 'colgroup' ).children( 'col' );
|
2298
|
-
storedSizes = storedSizes ||
|
2407
|
+
storedSizes = storedSizes || vars.storedSizes || [];
|
2299
2408
|
// process only if table ID or url match
|
2300
2409
|
if ( storedSizes.length ) {
|
2301
2410
|
for ( column = 0; column < c.columns; column++ ) {
|
2302
2411
|
// set saved resizable widths
|
2303
|
-
c.$headerIndexed[ column ]
|
2412
|
+
ts.resizable.setWidth( c.$headerIndexed[ column ], storedSizes[ column ], vars.overflow );
|
2304
2413
|
if ( $extra.length ) {
|
2305
2414
|
// stickyHeaders needs to modify min & max width as well
|
2306
|
-
|
2415
|
+
$temp = $extra.eq( column ).add( $col.eq( column ) );
|
2416
|
+
ts.resizable.setWidth( $temp, storedSizes[ column ], vars.overflow );
|
2307
2417
|
}
|
2308
2418
|
}
|
2309
|
-
|
2310
|
-
|
2419
|
+
$temp = $( c.namespace + '_extra_table' );
|
2420
|
+
if ( $temp.length && !ts.hasWidget( c.table, 'scroller' ) ) {
|
2421
|
+
ts.resizable.setWidth( $temp, c.$table.outerWidth(), vars.overflow );
|
2311
2422
|
}
|
2312
2423
|
}
|
2313
2424
|
},
|
@@ -2367,7 +2478,7 @@ ts.resizable = {
|
|
2367
2478
|
var namespace = c.namespace + 'tsresize';
|
2368
2479
|
wo.$resizable_container.children().bind( 'mousedown', function( event ) {
|
2369
2480
|
// save header cell and mouse position
|
2370
|
-
var column,
|
2481
|
+
var column,
|
2371
2482
|
vars = wo.resizable_,
|
2372
2483
|
$extras = $( c.namespace + '_extra_headers' ),
|
2373
2484
|
$header = $( event.target ).data( 'header' );
|
@@ -2386,11 +2497,7 @@ ts.resizable = {
|
|
2386
2497
|
vars.next = column;
|
2387
2498
|
|
2388
2499
|
vars.mouseXPosition = event.pageX;
|
2389
|
-
|
2390
|
-
for ( column = 0; column < c.columns; column++ ) {
|
2391
|
-
$this = c.$headerIndexed[ column ];
|
2392
|
-
vars.storedSizes[ column ] = $this.is(':visible') ? $this.width() : 0;
|
2393
|
-
}
|
2500
|
+
ts.resizable.updateStoredSizes( c, wo );
|
2394
2501
|
ts.resizable.toggleTextSelection( c, true );
|
2395
2502
|
});
|
2396
2503
|
|
@@ -2441,47 +2548,51 @@ ts.resizable = {
|
|
2441
2548
|
mouseMove : function( c, wo, event ) {
|
2442
2549
|
if ( wo.resizable_.mouseXPosition === 0 || !wo.resizable_.$target ) { return; }
|
2443
2550
|
// resize columns
|
2444
|
-
var
|
2551
|
+
var column,
|
2552
|
+
total = 0,
|
2553
|
+
vars = wo.resizable_,
|
2445
2554
|
$next = vars.$next,
|
2555
|
+
tar = vars.storedSizes[ vars.target ],
|
2446
2556
|
leftEdge = event.pageX - vars.mouseXPosition;
|
2447
|
-
if ( vars.
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2557
|
+
if ( vars.overflow ) {
|
2558
|
+
if ( tar + leftEdge > 0 ) {
|
2559
|
+
vars.storedSizes[ vars.target ] += leftEdge;
|
2560
|
+
ts.resizable.setWidth( vars.$target, vars.storedSizes[ vars.target ], true );
|
2561
|
+
// update the entire table width
|
2562
|
+
for ( column = 0; column < c.columns; column++ ) {
|
2563
|
+
total += vars.storedSizes[ column ];
|
2564
|
+
}
|
2565
|
+
ts.resizable.setWidth( c.$table.add( $( c.namespace + '_extra_table' ) ), total );
|
2566
|
+
}
|
2456
2567
|
if ( !$next.length ) {
|
2457
2568
|
// if expanding right-most column, scroll the wrapper
|
2458
2569
|
vars.$wrap[0].scrollLeft = c.$table.width();
|
2459
2570
|
}
|
2571
|
+
} else if ( vars.fullWidth ) {
|
2572
|
+
vars.storedSizes[ vars.target ] += leftEdge;
|
2573
|
+
vars.storedSizes[ vars.next ] -= leftEdge;
|
2574
|
+
ts.resizable.setWidths( c, wo );
|
2460
2575
|
} else {
|
2461
2576
|
vars.storedSizes[ vars.target ] += leftEdge;
|
2462
2577
|
ts.resizable.setWidths( c, wo );
|
2463
2578
|
}
|
2464
2579
|
vars.mouseXPosition = event.pageX;
|
2580
|
+
// dynamically update sticky header widths
|
2581
|
+
c.$table.trigger('stickyHeadersUpdate');
|
2465
2582
|
},
|
2466
2583
|
|
2467
2584
|
stopResize : function( c, wo ) {
|
2468
|
-
var
|
2469
|
-
|
2470
|
-
vars.
|
2471
|
-
|
2472
|
-
vars.storedSizes
|
2473
|
-
|
2474
|
-
$this = c.$headerIndexed[ column ];
|
2475
|
-
vars.storedSizes[ column ] = $this.is(':visible') ? $this.width() : 0;
|
2476
|
-
}
|
2477
|
-
if ( wo.resizable !== false ) {
|
2478
|
-
// save all column widths
|
2479
|
-
ts.storage( c.table, ts.css.resizableStorage, vars.storedSizes );
|
2480
|
-
}
|
2585
|
+
var vars = wo.resizable_;
|
2586
|
+
ts.resizable.updateStoredSizes( c, wo );
|
2587
|
+
if ( vars.useStorage ) {
|
2588
|
+
// save all column widths
|
2589
|
+
ts.storage( c.table, ts.css.resizableStorage, vars.storedSizes );
|
2590
|
+
ts.storage( c.table, 'tablesorter-table-resized-width', c.$table.width() );
|
2481
2591
|
}
|
2482
2592
|
vars.mouseXPosition = 0;
|
2483
2593
|
vars.$target = vars.$next = null;
|
2484
|
-
|
2594
|
+
// will update stickyHeaders, just in case, see #912
|
2595
|
+
c.$table.trigger('stickyHeadersUpdate');
|
2485
2596
|
}
|
2486
2597
|
};
|
2487
2598
|
|
@@ -2492,11 +2603,12 @@ ts.addWidget({
|
|
2492
2603
|
id: "resizable",
|
2493
2604
|
priority: 40,
|
2494
2605
|
options: {
|
2495
|
-
resizable : true,
|
2606
|
+
resizable : true, // save column widths to storage
|
2496
2607
|
resizable_addLastColumn : false,
|
2497
2608
|
resizable_widths : [],
|
2498
2609
|
resizable_throttle : false, // set to true (5ms) or any number 0-10 range
|
2499
|
-
resizable_targetLast : false
|
2610
|
+
resizable_targetLast : false,
|
2611
|
+
resizable_fullWidth : null
|
2500
2612
|
},
|
2501
2613
|
init: function(table, thisWidget, c, wo) {
|
2502
2614
|
ts.resizable.init( c, wo );
|
@@ -2520,19 +2632,28 @@ ts.resizableReset = function( table, refreshing ) {
|
|
2520
2632
|
$( table ).each(function(){
|
2521
2633
|
var index, $t,
|
2522
2634
|
c = this.config,
|
2523
|
-
wo = c && c.widgetOptions
|
2635
|
+
wo = c && c.widgetOptions,
|
2636
|
+
vars = wo.resizable_;
|
2524
2637
|
if ( table && c && c.$headerIndexed.length ) {
|
2638
|
+
// restore the initial table width
|
2639
|
+
if ( vars.overflow && vars.tableWidth ) {
|
2640
|
+
ts.resizable.setWidth( c.$table, vars.tableWidth, true );
|
2641
|
+
if ( vars.useStorage ) {
|
2642
|
+
ts.storage( table, 'tablesorter-table-resized-width', 'auto' );
|
2643
|
+
}
|
2644
|
+
}
|
2525
2645
|
for ( index = 0; index < c.columns; index++ ) {
|
2526
2646
|
$t = c.$headerIndexed[ index ];
|
2527
2647
|
if ( wo.resizable_widths && wo.resizable_widths[ index ] ) {
|
2528
|
-
|
2648
|
+
ts.resizable.setWidth( $t, wo.resizable_widths[ index ], vars.overflow );
|
2529
2649
|
} else if ( !$t.hasClass( 'resizable-false' ) ) {
|
2530
2650
|
// don't clear the width of any column that is not resizable
|
2531
|
-
|
2651
|
+
ts.resizable.setWidth( $t, '', vars.overflow );
|
2532
2652
|
}
|
2533
2653
|
}
|
2654
|
+
|
2534
2655
|
// reset stickyHeader widths
|
2535
|
-
|
2656
|
+
c.$table.trigger( 'stickyHeadersUpdate' );
|
2536
2657
|
if ( ts.storage && !refreshing ) {
|
2537
2658
|
ts.storage( this, ts.css.resizableStorage, {} );
|
2538
2659
|
}
|