This commit is contained in:
Rob Garrison 2017-12-13 15:17:20 -06:00
parent e496cbfe05
commit a225a40378
16 changed files with 233 additions and 174 deletions

View File

@ -104,6 +104,28 @@ If you would like to contribute, please...
View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/Changes).
#### <a name="v2.29.1">Version 2.29.1</a> (12/13/2017)
* Core:
* Fix non-typical use of selectorHeaders. See [issue #1459](https://github.com/Mottie/tablesorter/issues/1459).
* Update external header icons on sort. Fixes [issue #1483](https://github.com/Mottie/tablesorter/issues/1483).
* Remove an empty block.
* Filter:
* Select exact matches ignore "and" and "or" keywords. Fixes [issue #1486](https://github.com/Mottie/tablesorter/issues/1486).
* Resizable:
* `addLastColumn` stops adding handles to hidden columns. Fixes [issue #1485](https://github.com/Mottie/tablesorter/issues/1485).
* Scroller:
* Adjust columns on `filterInit`. See [issue #1468](https://github.com/Mottie/tablesorter/issues/1468).
* Vertical Group:
* New widget added. See [demo](https://mottie.github.io/tablesorter/docs/example-widget-vertical-group.html).
* Thanks to [aavmurphy](https://github.com/aavmurphy) for sharing the code. See [issue #1469](https://github.com/Mottie/tablesorter/issues/1469) and [PR #1470](https://github.com/Mottie/tablesorter/pull/1470).
* Docs:
* Fix pager example.
* List all contained IP parsers. Fixes [issue #1484](https://github.com/Mottie/tablesorter/issues/1484).
* Fix Bootstrap v2 demo; restored gyphs images.
* Meta:
* Update authors.
#### <a name="v2.29.0">Version 2.29.0</a> (9/27/2017)
* Core:
@ -164,15 +186,3 @@ View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/C
* Use src files in filter formatter demo for testing.
* Meta:
* Include `js` & `css` folders with bower installs.
#### <a name="v2.28.14">Version 2.28.14</a> (6/8/2017)
* Core:
* Show console error for mismatched column count. See [issue #1415](https://github.com/Mottie/tablesorter/issues/1415).
* Pager:
* (addon) Ensure ajax is called after filter widget init. Fixes [issue #1389](https://github.com/Mottie/tablesorter/issues/1389).
* (addon) Fix height issues for certain browsers (border-spacing). See [pull #1418](https://github.com/Mottie/tablesorter/pull/1418); thanks [@DoctorWhite](https://github.com/DoctorWhite)
* (widget) Apply height adjustment code to pager widget.
* Use selectorRemove to remove error rows. Removes error rows with dynamically changed class names.
* Meta:
* Added [AUTHORS](https://github.com/Mottie/tablesorter/blob/master/AUTHORS) file.

View File

@ -1,4 +1,4 @@
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/*! tablesorter (FORK) - updated 12-13-2017 (v2.29.1)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -10,7 +10,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.29.0 *//*
/*! TableSorter (FORK) v2.29.1 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -34,7 +34,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.29.0',
version : '2.29.1',
parsers : [],
widgets : [],
@ -526,8 +526,7 @@
if ( c.delayInit && ts.isEmptyObject( c.cache ) ) {
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = ts.getHeaderCell( $( this ) );
$cell = ts.getClosest( $( this ), '.' + ts.css.header );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -567,10 +566,15 @@
'';
// redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
var configHeaders, header, column, template, tmp, $th,
var configHeaders, header, column, template, tmp,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
if ( ts.getClosest( $elem, 'tr' ).hasClass( c.cssIgnoreRow ) ) { return; }
// transfer data-column to element if not th/td - #1459
if ( !/(th|td)/i.test( elem.nodeName ) ) {
tmp = ts.getClosest( $elem, 'th, td' );
$elem.attr( 'data-column', tmp.attr( 'data-column' ) );
}
// make sure to get header cell & not column indexed cell
configHeaders = ts.getColumnData( c.table, c.headers, index, true );
// save original header content
@ -593,9 +597,7 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.attr( 'data-column' ), 10 );
column = parseInt( $elem.attr( 'data-column' ), 10 );
elem.column = column;
tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
// this may get updated numerous times if there are multiple rows
@ -631,6 +633,7 @@
if ( ts.isEmptyObject( c.sortVars[ indx ] ) ) {
c.sortVars[ indx ] = {};
}
// Use c.$headers.parent() in case selectorHeaders doesn't point to the th/td
$temp = c.$headers.filter( '[data-column="' + indx + '"]' );
// target sortable column cells, unless there are none, then use non-sortable cells
// .last() added in jQuery 1.4; use .filter(':last') to maintain compatibility with jQuery v1.2.6
@ -1094,6 +1097,15 @@
css = [ ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc ],
cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ],
aria = [ 'ascending', 'descending' ],
updateColumnSort = function($el, index) {
$el
.removeClass( none )
.addClass( css[ index ] )
.attr( 'aria-sort', aria[ index ] )
.find( '.' + ts.css.icon )
.removeClass( cssIcon[ 2 ] )
.addClass( cssIcon[ index ] );
},
// find the footer
$extras = c.$table
.find( 'tfoot tr' )
@ -1132,7 +1144,7 @@
var include = true,
$el = c.$headers.eq( i ),
col = parseInt( $el.attr( 'data-column' ), 10 ),
end = col + c.$headers[ i ].colSpan;
end = col + ts.getClosest( $el, 'th, td' )[0].colSpan;
for ( ; col < end; col++ ) {
include = include ? include || ts.isValueInArray( col, c.sortList ) > -1 : false;
}
@ -1146,23 +1158,13 @@
if ( $sorted.length ) {
for ( column = 0; column < $sorted.length; column++ ) {
if ( !$sorted[ column ].sortDisabled ) {
$sorted
.eq( column )
.removeClass( none )
.addClass( css[ list[ indx ][ 1 ] ] )
.attr( 'aria-sort', aria[ list[ indx ][ 1 ] ] )
.find( '.' + ts.css.icon )
.removeClass( cssIcon[ 2 ] )
.addClass( cssIcon[ list[ indx ][ 1 ] ] );
updateColumnSort( $sorted.eq( column ) , list[ indx ][ 1 ] );
}
}
// add sorted class to footer & extra headers, if they exist
if ( $extras.length ) {
$extras
.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' )
.removeClass( none )
.addClass( css[ list[ indx ][ 1 ] ] );
}
}
// add sorted class to footer & extra headers, if they exist
if ( $extras.length ) {
updateColumnSort( $extras.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' ), list[ indx ][ 1 ] );
}
}
}
@ -1173,29 +1175,20 @@
}
},
// This function does NOT return closest if the $el matches the selector
getClosest : function( $el, selector ) {
return $.fn.closest ?
$el.closest( selector ) :
$el.parents( selector ).filter( ':first' );
},
getHeaderCell : function( $el ) {
// jQuery v1.2.6 doesn't have closest()
if ( $.fn.closest ) {
return $el.closest( 'th, td' );
return $el.closest( selector );
}
return /TH|TD/.test( $el[0].nodeName ) ?
return $el.is( selector ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
$el.parents( selector ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
var column = parseInt( $header.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1563,10 +1556,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
th = ts.getClosest( $( cell ), 'th, td' ),
col = parseInt( th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
th = th[0];
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -1601,8 +1594,8 @@
if ( dir < 2 ) {
c.sortList[ c.sortList.length ] = [ col, dir ];
// add other columns if header spans across multiple
if ( cell.colSpan > 1 ) {
for ( indx = 1; indx < cell.colSpan; indx++ ) {
if ( th.colSpan > 1 ) {
for ( indx = 1; indx < th.colSpan; indx++ ) {
c.sortList[ c.sortList.length ] = [ col + indx, dir ];
// update count on columns in colSpan
c.sortVars[ col + indx ].count = $.inArray( dir, order );
@ -1634,8 +1627,8 @@
if ( dir < 2 ) {
c.sortList[ c.sortList.length ] = [ col, dir ];
// add other columns if header spans across multiple
if ( cell.colSpan > 1 ) {
for ( indx = 1; indx < cell.colSpan; indx++ ) {
if ( th.colSpan > 1 ) {
for ( indx = 1; indx < th.colSpan; indx++ ) {
c.sortList[ c.sortList.length ] = [ col + indx, dir ];
// update count on columns in colSpan
c.sortVars[ col + indx ].count = $.inArray( dir, order );
@ -2404,7 +2397,7 @@
$cells = ( $headers || c.$headers ),
// c.$headerIndexed is not defined initially
$cell = c.$headerIndexed && c.$headerIndexed[ indx ] ||
$cells.filter( '[data-column="' + indx + '"]:last' );
$cells.find( '[data-column="' + indx + '"]:last' );
if ( typeof obj[ indx ] !== 'undefined' ) {
return getCell ? obj[ indx ] : obj[ $cells.index( $cell ) ];
}
@ -4406,6 +4399,7 @@
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
matches = tsf.types[ffxn]( c, data, vars );
if ( matches !== null ) {
data.matchedOn = ffxn;
filterMatched = matches;
}
}
@ -4453,6 +4447,7 @@
tsf.multipleColumns( c, wo.filter_$anyMatch ) :
[];
data.$cells = data.$row.children();
data.matchedOn = null;
if ( data.anyMatchFlag && columnIndex.length > 1 || ( data.anyMatchFilter && !hasAnyMatchInput ) ) {
data.anyMatch = true;
data.isMatch = true;
@ -4554,7 +4549,9 @@
// cycle through the different filters
// filters return a boolean or null if nothing matches
filterMatched = tsf.processTypes( c, data, vars );
if ( filterMatched !== null ) {
// select with exact match; ignore "and" or "or" within the text; fixes #1486
txt = fxn === true && (data.matchedOn === 'and' || data.matchedOn === 'or');
if ( filterMatched !== null && !txt) {
result = filterMatched;
// Look for match, and add child row data for matching
} else {
@ -5713,7 +5710,10 @@
columns = c.columns - 1,
$header = $this.data( 'header' );
if ( !$header ) { return; } // see #859
if ( !$header.is(':visible') ) {
if (
!$header.is(':visible') ||
( !wo.resizable_addLastColumn && ts.resizable.checkVisibleColumns(c, column) )
) {
$this.hide();
} else if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
$this.css({
@ -5725,6 +5725,16 @@
});
},
// Fixes #1485
checkVisibleColumns: function( c, column ) {
var i,
len = 0;
for ( i = column + 1; i < c.columns; i++ ) {
len += c.$headerIndexed[i].is( ':visible' ) ? 1 : 0;
}
return len === 0;
},
// prevent text selection while dragging resize bar
toggleTextSelection : function( c, wo, toggle ) {
var namespace = c.namespace + 'tsresize';

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.29.0 *//*
/*! TableSorter (FORK) v2.29.1 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -32,7 +32,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.29.0',
version : '2.29.1',
parsers : [],
widgets : [],
@ -524,8 +524,7 @@
if ( c.delayInit && ts.isEmptyObject( c.cache ) ) {
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = ts.getHeaderCell( $( this ) );
$cell = ts.getClosest( $( this ), '.' + ts.css.header );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -565,10 +564,15 @@
'';
// redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
var configHeaders, header, column, template, tmp, $th,
var configHeaders, header, column, template, tmp,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
if ( ts.getClosest( $elem, 'tr' ).hasClass( c.cssIgnoreRow ) ) { return; }
// transfer data-column to element if not th/td - #1459
if ( !/(th|td)/i.test( elem.nodeName ) ) {
tmp = ts.getClosest( $elem, 'th, td' );
$elem.attr( 'data-column', tmp.attr( 'data-column' ) );
}
// make sure to get header cell & not column indexed cell
configHeaders = ts.getColumnData( c.table, c.headers, index, true );
// save original header content
@ -591,9 +595,7 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.attr( 'data-column' ), 10 );
column = parseInt( $elem.attr( 'data-column' ), 10 );
elem.column = column;
tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
// this may get updated numerous times if there are multiple rows
@ -629,6 +631,7 @@
if ( ts.isEmptyObject( c.sortVars[ indx ] ) ) {
c.sortVars[ indx ] = {};
}
// Use c.$headers.parent() in case selectorHeaders doesn't point to the th/td
$temp = c.$headers.filter( '[data-column="' + indx + '"]' );
// target sortable column cells, unless there are none, then use non-sortable cells
// .last() added in jQuery 1.4; use .filter(':last') to maintain compatibility with jQuery v1.2.6
@ -1092,6 +1095,15 @@
css = [ ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc ],
cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ],
aria = [ 'ascending', 'descending' ],
updateColumnSort = function($el, index) {
$el
.removeClass( none )
.addClass( css[ index ] )
.attr( 'aria-sort', aria[ index ] )
.find( '.' + ts.css.icon )
.removeClass( cssIcon[ 2 ] )
.addClass( cssIcon[ index ] );
},
// find the footer
$extras = c.$table
.find( 'tfoot tr' )
@ -1130,7 +1142,7 @@
var include = true,
$el = c.$headers.eq( i ),
col = parseInt( $el.attr( 'data-column' ), 10 ),
end = col + c.$headers[ i ].colSpan;
end = col + ts.getClosest( $el, 'th, td' )[0].colSpan;
for ( ; col < end; col++ ) {
include = include ? include || ts.isValueInArray( col, c.sortList ) > -1 : false;
}
@ -1144,23 +1156,13 @@
if ( $sorted.length ) {
for ( column = 0; column < $sorted.length; column++ ) {
if ( !$sorted[ column ].sortDisabled ) {
$sorted
.eq( column )
.removeClass( none )
.addClass( css[ list[ indx ][ 1 ] ] )
.attr( 'aria-sort', aria[ list[ indx ][ 1 ] ] )
.find( '.' + ts.css.icon )
.removeClass( cssIcon[ 2 ] )
.addClass( cssIcon[ list[ indx ][ 1 ] ] );
updateColumnSort( $sorted.eq( column ) , list[ indx ][ 1 ] );
}
}
// add sorted class to footer & extra headers, if they exist
if ( $extras.length ) {
$extras
.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' )
.removeClass( none )
.addClass( css[ list[ indx ][ 1 ] ] );
}
}
// add sorted class to footer & extra headers, if they exist
if ( $extras.length ) {
updateColumnSort( $extras.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' ), list[ indx ][ 1 ] );
}
}
}
@ -1171,29 +1173,20 @@
}
},
// This function does NOT return closest if the $el matches the selector
getClosest : function( $el, selector ) {
return $.fn.closest ?
$el.closest( selector ) :
$el.parents( selector ).filter( ':first' );
},
getHeaderCell : function( $el ) {
// jQuery v1.2.6 doesn't have closest()
if ( $.fn.closest ) {
return $el.closest( 'th, td' );
return $el.closest( selector );
}
return /TH|TD/.test( $el[0].nodeName ) ?
return $el.is( selector ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
$el.parents( selector ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
var column = parseInt( $header.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1561,10 +1554,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
th = ts.getClosest( $( cell ), 'th, td' ),
col = parseInt( th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
th = th[0];
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -1599,8 +1592,8 @@
if ( dir < 2 ) {
c.sortList[ c.sortList.length ] = [ col, dir ];
// add other columns if header spans across multiple
if ( cell.colSpan > 1 ) {
for ( indx = 1; indx < cell.colSpan; indx++ ) {
if ( th.colSpan > 1 ) {
for ( indx = 1; indx < th.colSpan; indx++ ) {
c.sortList[ c.sortList.length ] = [ col + indx, dir ];
// update count on columns in colSpan
c.sortVars[ col + indx ].count = $.inArray( dir, order );
@ -1632,8 +1625,8 @@
if ( dir < 2 ) {
c.sortList[ c.sortList.length ] = [ col, dir ];
// add other columns if header spans across multiple
if ( cell.colSpan > 1 ) {
for ( indx = 1; indx < cell.colSpan; indx++ ) {
if ( th.colSpan > 1 ) {
for ( indx = 1; indx < th.colSpan; indx++ ) {
c.sortList[ c.sortList.length ] = [ col + indx, dir ];
// update count on columns in colSpan
c.sortVars[ col + indx ].count = $.inArray( dir, order );
@ -2402,7 +2395,7 @@
$cells = ( $headers || c.$headers ),
// c.$headerIndexed is not defined initially
$cell = c.$headerIndexed && c.$headerIndexed[ indx ] ||
$cells.filter( '[data-column="' + indx + '"]:last' );
$cells.find( '[data-column="' + indx + '"]:last' );
if ( typeof obj[ indx ] !== 'undefined' ) {
return getCell ? obj[ indx ] : obj[ $cells.index( $cell ) ];
}

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/*! tablesorter (FORK) - updated 12-13-2017 (v2.29.1)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -1519,6 +1519,7 @@
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
matches = tsf.types[ffxn]( c, data, vars );
if ( matches !== null ) {
data.matchedOn = ffxn;
filterMatched = matches;
}
}
@ -1566,6 +1567,7 @@
tsf.multipleColumns( c, wo.filter_$anyMatch ) :
[];
data.$cells = data.$row.children();
data.matchedOn = null;
if ( data.anyMatchFlag && columnIndex.length > 1 || ( data.anyMatchFilter && !hasAnyMatchInput ) ) {
data.anyMatch = true;
data.isMatch = true;
@ -1667,7 +1669,9 @@
// cycle through the different filters
// filters return a boolean or null if nothing matches
filterMatched = tsf.processTypes( c, data, vars );
if ( filterMatched !== null ) {
// select with exact match; ignore "and" or "or" within the text; fixes #1486
txt = fxn === true && (data.matchedOn === 'and' || data.matchedOn === 'or');
if ( filterMatched !== null && !txt) {
result = filterMatched;
// Look for match, and add child row data for matching
} else {
@ -2826,7 +2830,10 @@
columns = c.columns - 1,
$header = $this.data( 'header' );
if ( !$header ) { return; } // see #859
if ( !$header.is(':visible') ) {
if (
!$header.is(':visible') ||
( !wo.resizable_addLastColumn && ts.resizable.checkVisibleColumns(c, column) )
) {
$this.hide();
} else if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
$this.css({
@ -2838,6 +2845,16 @@
});
},
// Fixes #1485
checkVisibleColumns: function( c, column ) {
var i,
len = 0;
for ( i = column + 1; i < c.columns; i++ ) {
len += c.$headerIndexed[i].is( ':visible' ) ? 1 : 0;
}
return len === 0;
},
// prevent text selection while dragging resize bar
toggleTextSelection : function( c, wo, toggle ) {
var namespace = c.namespace + 'tsresize';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
/*! Widget: vertical-group (BETA) - updated 12/13/2017 (v2.29.1) */
!function(r){"use strict";function e(r){r.removeClass(i.verticalGroupHide+" "+i.verticalGroupShow)}function a(r,e,a){e.parent().removeClass(r.zebra[(a+1)%2]).addClass(r.zebra[a%2])}function o(o,l,s,c){var u=-1,v=o.tBodies[0].rows,d=(o.tHead.rows,t.hasWidget(o,"zebra")),p=[],n=[];if(!s.vertical_group_lock){if(s.vertical_group_lock=!0,""===(p=r.map(l.$headerIndexed,function(r){return r.hasClass(i.verticalGroupHeader)?1:""})).join(""))return e(r(v).find("."+i.verticalGroupHide+",."+i.verticalGroupShow)),void(s.vertical_group_lock=!1);for(var h=0;h<v.length;h++)for(var G=!1,f=0;f<l.columns;f++)if(p[f]&&v[h].cells[f]){var g=r(v[h].cells[f]),C=t.isValueInArray(f,l.sortList),w=g.html();C<0?e(g):G||w!==n[f]?0===C&&(G=!0,g.hasClass(i.verticalGroupShow)||g.addClass(i.verticalGroupShow),g.removeClass(i.verticalGroupHide),d&&a(s,g,C?u:++u)):(g.hasClass(i.verticalGroupHide)||g.addClass(i.verticalGroupHide),d&&a(s,g,u),g.removeClass(i.verticalGroupShow)),n[f]=w}else u++;s.vertical_group_lock=!1}}var t=r.tablesorter,i=t.css;r.extend(t.css,{verticalGroupHeader:"tablesorter-vertical-group",verticalGroupHide:"tablesorter-vertical-group-hide",verticalGroupShow:"tablesorter-vertical-group-show"}),t.addWidget({id:"vertical-group",priority:99,init:o,format:o})}(jQuery);

View File

@ -4,7 +4,7 @@
*/
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/*! tablesorter (FORK) - updated 12-13-2017 (v2.29.1)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -16,7 +16,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.29.0 *//*
/*! TableSorter (FORK) v2.29.1 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -40,7 +40,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.29.0',
version : '2.29.1',
parsers : [],
widgets : [],
@ -532,8 +532,7 @@
if ( c.delayInit && ts.isEmptyObject( c.cache ) ) {
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = ts.getHeaderCell( $( this ) );
$cell = ts.getClosest( $( this ), '.' + ts.css.header );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -573,10 +572,15 @@
'';
// redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683
c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) {
var configHeaders, header, column, template, tmp, $th,
var configHeaders, header, column, template, tmp,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
if ( ts.getClosest( $elem, 'tr' ).hasClass( c.cssIgnoreRow ) ) { return; }
// transfer data-column to element if not th/td - #1459
if ( !/(th|td)/i.test( elem.nodeName ) ) {
tmp = ts.getClosest( $elem, 'th, td' );
$elem.attr( 'data-column', tmp.attr( 'data-column' ) );
}
// make sure to get header cell & not column indexed cell
configHeaders = ts.getColumnData( c.table, c.headers, index, true );
// save original header content
@ -599,9 +603,7 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.attr( 'data-column' ), 10 );
column = parseInt( $elem.attr( 'data-column' ), 10 );
elem.column = column;
tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder );
// this may get updated numerous times if there are multiple rows
@ -637,6 +639,7 @@
if ( ts.isEmptyObject( c.sortVars[ indx ] ) ) {
c.sortVars[ indx ] = {};
}
// Use c.$headers.parent() in case selectorHeaders doesn't point to the th/td
$temp = c.$headers.filter( '[data-column="' + indx + '"]' );
// target sortable column cells, unless there are none, then use non-sortable cells
// .last() added in jQuery 1.4; use .filter(':last') to maintain compatibility with jQuery v1.2.6
@ -1100,6 +1103,15 @@
css = [ ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc ],
cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ],
aria = [ 'ascending', 'descending' ],
updateColumnSort = function($el, index) {
$el
.removeClass( none )
.addClass( css[ index ] )
.attr( 'aria-sort', aria[ index ] )
.find( '.' + ts.css.icon )
.removeClass( cssIcon[ 2 ] )
.addClass( cssIcon[ index ] );
},
// find the footer
$extras = c.$table
.find( 'tfoot tr' )
@ -1138,7 +1150,7 @@
var include = true,
$el = c.$headers.eq( i ),
col = parseInt( $el.attr( 'data-column' ), 10 ),
end = col + c.$headers[ i ].colSpan;
end = col + ts.getClosest( $el, 'th, td' )[0].colSpan;
for ( ; col < end; col++ ) {
include = include ? include || ts.isValueInArray( col, c.sortList ) > -1 : false;
}
@ -1152,23 +1164,13 @@
if ( $sorted.length ) {
for ( column = 0; column < $sorted.length; column++ ) {
if ( !$sorted[ column ].sortDisabled ) {
$sorted
.eq( column )
.removeClass( none )
.addClass( css[ list[ indx ][ 1 ] ] )
.attr( 'aria-sort', aria[ list[ indx ][ 1 ] ] )
.find( '.' + ts.css.icon )
.removeClass( cssIcon[ 2 ] )
.addClass( cssIcon[ list[ indx ][ 1 ] ] );
updateColumnSort( $sorted.eq( column ) , list[ indx ][ 1 ] );
}
}
// add sorted class to footer & extra headers, if they exist
if ( $extras.length ) {
$extras
.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' )
.removeClass( none )
.addClass( css[ list[ indx ][ 1 ] ] );
}
}
// add sorted class to footer & extra headers, if they exist
if ( $extras.length ) {
updateColumnSort( $extras.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' ), list[ indx ][ 1 ] );
}
}
}
@ -1179,29 +1181,20 @@
}
},
// This function does NOT return closest if the $el matches the selector
getClosest : function( $el, selector ) {
return $.fn.closest ?
$el.closest( selector ) :
$el.parents( selector ).filter( ':first' );
},
getHeaderCell : function( $el ) {
// jQuery v1.2.6 doesn't have closest()
if ( $.fn.closest ) {
return $el.closest( 'th, td' );
return $el.closest( selector );
}
return /TH|TD/.test( $el[0].nodeName ) ?
return $el.is( selector ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
$el.parents( selector ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
var column = parseInt( $header.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1569,10 +1562,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
th = ts.getClosest( $( cell ), 'th, td' ),
col = parseInt( th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
th = th[0];
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -1607,8 +1600,8 @@
if ( dir < 2 ) {
c.sortList[ c.sortList.length ] = [ col, dir ];
// add other columns if header spans across multiple
if ( cell.colSpan > 1 ) {
for ( indx = 1; indx < cell.colSpan; indx++ ) {
if ( th.colSpan > 1 ) {
for ( indx = 1; indx < th.colSpan; indx++ ) {
c.sortList[ c.sortList.length ] = [ col + indx, dir ];
// update count on columns in colSpan
c.sortVars[ col + indx ].count = $.inArray( dir, order );
@ -1640,8 +1633,8 @@
if ( dir < 2 ) {
c.sortList[ c.sortList.length ] = [ col, dir ];
// add other columns if header spans across multiple
if ( cell.colSpan > 1 ) {
for ( indx = 1; indx < cell.colSpan; indx++ ) {
if ( th.colSpan > 1 ) {
for ( indx = 1; indx < th.colSpan; indx++ ) {
c.sortList[ c.sortList.length ] = [ col + indx, dir ];
// update count on columns in colSpan
c.sortVars[ col + indx ].count = $.inArray( dir, order );
@ -2410,7 +2403,7 @@
$cells = ( $headers || c.$headers ),
// c.$headerIndexed is not defined initially
$cell = c.$headerIndexed && c.$headerIndexed[ indx ] ||
$cells.filter( '[data-column="' + indx + '"]:last' );
$cells.find( '[data-column="' + indx + '"]:last' );
if ( typeof obj[ indx ] !== 'undefined' ) {
return getCell ? obj[ indx ] : obj[ $cells.index( $cell ) ];
}
@ -4412,6 +4405,7 @@
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
matches = tsf.types[ffxn]( c, data, vars );
if ( matches !== null ) {
data.matchedOn = ffxn;
filterMatched = matches;
}
}
@ -4459,6 +4453,7 @@
tsf.multipleColumns( c, wo.filter_$anyMatch ) :
[];
data.$cells = data.$row.children();
data.matchedOn = null;
if ( data.anyMatchFlag && columnIndex.length > 1 || ( data.anyMatchFilter && !hasAnyMatchInput ) ) {
data.anyMatch = true;
data.isMatch = true;
@ -4560,7 +4555,9 @@
// cycle through the different filters
// filters return a boolean or null if nothing matches
filterMatched = tsf.processTypes( c, data, vars );
if ( filterMatched !== null ) {
// select with exact match; ignore "and" or "or" within the text; fixes #1486
txt = fxn === true && (data.matchedOn === 'and' || data.matchedOn === 'or');
if ( filterMatched !== null && !txt) {
result = filterMatched;
// Look for match, and add child row data for matching
} else {
@ -5719,7 +5716,10 @@
columns = c.columns - 1,
$header = $this.data( 'header' );
if ( !$header ) { return; } // see #859
if ( !$header.is(':visible') ) {
if (
!$header.is(':visible') ||
( !wo.resizable_addLastColumn && ts.resizable.checkVisibleColumns(c, column) )
) {
$this.hide();
} else if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
$this.css({
@ -5731,6 +5731,16 @@
});
},
// Fixes #1485
checkVisibleColumns: function( c, column ) {
var i,
len = 0;
for ( i = column + 1; i < c.columns; i++ ) {
len += c.$headerIndexed[i].is( ':visible' ) ? 1 : 0;
}
return len === 0;
},
// prevent text selection while dragging resize bar
toggleTextSelection : function( c, wo, toggle ) {
var namespace = c.namespace + 'tsresize';

View File

@ -1,4 +1,4 @@
/*! TableSorter (FORK) v2.29.0 *//*
/*! TableSorter (FORK) v2.29.1 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -22,7 +22,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.29.0',
version : '2.29.1',
parsers : [],
widgets : [],

View File

@ -4,7 +4,7 @@
*/
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/*! tablesorter (FORK) - updated 12-13-2017 (v2.29.1)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -1525,6 +1525,7 @@
if ( $.inArray( ffxn, vars.excludeMatch ) < 0 && matches === null ) {
matches = tsf.types[ffxn]( c, data, vars );
if ( matches !== null ) {
data.matchedOn = ffxn;
filterMatched = matches;
}
}
@ -1572,6 +1573,7 @@
tsf.multipleColumns( c, wo.filter_$anyMatch ) :
[];
data.$cells = data.$row.children();
data.matchedOn = null;
if ( data.anyMatchFlag && columnIndex.length > 1 || ( data.anyMatchFilter && !hasAnyMatchInput ) ) {
data.anyMatch = true;
data.isMatch = true;
@ -1673,7 +1675,9 @@
// cycle through the different filters
// filters return a boolean or null if nothing matches
filterMatched = tsf.processTypes( c, data, vars );
if ( filterMatched !== null ) {
// select with exact match; ignore "and" or "or" within the text; fixes #1486
txt = fxn === true && (data.matchedOn === 'and' || data.matchedOn === 'or');
if ( filterMatched !== null && !txt) {
result = filterMatched;
// Look for match, and add child row data for matching
} else {
@ -2832,7 +2836,10 @@
columns = c.columns - 1,
$header = $this.data( 'header' );
if ( !$header ) { return; } // see #859
if ( !$header.is(':visible') ) {
if (
!$header.is(':visible') ||
( !wo.resizable_addLastColumn && ts.resizable.checkVisibleColumns(c, column) )
) {
$this.hide();
} else if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
$this.css({
@ -2844,6 +2851,16 @@
});
},
// Fixes #1485
checkVisibleColumns: function( c, column ) {
var i,
len = 0;
for ( i = column + 1; i < c.columns; i++ ) {
len += c.$headerIndexed[i].is( ':visible' ) ? 1 : 0;
}
return len === 0;
},
// prevent text selection while dragging resize bar
toggleTextSelection : function( c, wo, toggle ) {
var namespace = c.namespace + 'tsresize';

View File

@ -1,7 +1,7 @@
{
"name": "tablesorter",
"title": "tablesorter",
"version": "2.29.0",
"version": "2.29.1",
"description": "tablesorter (FORK) is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.",
"author": {
"name": "Christian Bach",

View File

@ -1,7 +1,7 @@
{
"name": "tablesorter",
"title": "tablesorter",
"version": "2.29.0",
"version": "2.29.1",
"description": "tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.\n\nThis forked version adds lots of new enhancements including: alphanumeric sorting, pager callback functons, multiple widgets providing column styling, ui theme application, sticky headers, column filters and resizer, as well as extended documentation with a lot more demos.",
"author": {
"name": "Christian Bach",