Merge branch 'master' into gh-pages

This commit is contained in:
Rob Garrison 2017-09-27 21:14:19 -05:00
commit fe47eada94
51 changed files with 896 additions and 417 deletions

View File

@ -280,7 +280,8 @@ module.exports = function( grunt ) {
options: {
output: {
comments: /^!/,
beautify: false
beautify: false,
ie8: true
},
report: 'gzip'
},

View File

@ -62,7 +62,7 @@ tablesorter (FORK) is a jQuery plugin for turning a standard HTML table with THE
### Related Projects
* [Plugin for Rails](https://github.com/themilkman/jquery-tablesorter-rails). Maintained by [themilkman](https://github.com/themilkman).
* [UserFrosting](https://github.com/alexweissman/UserFrosting) (A secure, modern user management system for PHP that uses tablesorter) by [alexweissman](https://github.com/alexweissman).
* [UserFrosting](https://www.userfrosting.com) (A secure, modern user management system for PHP that uses tablesorter) by [@alexweissman](https://github.com/alexweissman).
* [Grav CMS](https://getgrav.org/): `bin/gpm install tablesorter` ([ref](https://github.com/Perlkonig/grav-plugin-tablesorter)).
* [tablesorter-pagercontrols](https://github.com/isg-software/tablesorter-pagercontrols) – programmatically adds pager controls below a table and applies the pager add-on for large HTML tables by [isg-software](https://github.com/isg-software).
@ -104,6 +104,45 @@ If you would like to contribute, please...
View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/Changes).
#### <a name="v2.29.0">Version 2.29.0</a> (9/27/2017)
* Core:
* Include callback method for ["applyWidgets"](https://mottie.github.io/tablesorter/docs/index.html#applywidgets).
* Add ["widgetRemoveEnd" event](https://mottie.github.io/tablesorter/docs/index.html#widgetremoveend). Fixes [issue #1430](https://github.com/Mottie/tablesorter/issues/1430).
* Clarify warning message (widget enabled but code not loaded).
* Target header cells for data-column. Fixes [issue #1459](https://github.com/Mottie/tablesorter/issues/1459).
* ColumnSelector:
* Add [`classHasSpan` option](https://mottie.github.io/tablesorter/docs/example-widget-column-selector.html#column-selector-class-has-span).
* Fix compatibility with grouping widget.
* Grouping:
* Fix compatibility with columnSelector widget.
* Output:
* Modify internal `process` function to allow outputting of data without adding it to the table.
* Resizable:
* Add resizableComplete event. Fixes [issue #1444](https://github.com/Mottie/tablesorter/issues/1444).
* Scroller:
* Save position to fix `scroller_upAfterSort: false`; See [PR #1441](https://github.com/Mottie/tablesorter/pull/1441). This should fix [issue #1297](https://github.com/Mottie/tablesorter/issues/1297) - The current position is now saved on scroll so it can be restored after sorting; thanks [@lbodtke](https://github.com/lbodtke)!
* Update scroll position after fixing columns.
* Sort2Hash:
* Prevent sort2Hash from adding extraneous entries to browser history. Use `window.location.replace` to update the browser URL only, rather than `window.location.hash`, which modifies the browser history. See [PR #1447](https://github.com/Mottie/tablesorter/pull/1447); thanks [@alexweissman](https://github.com/alexweissman)!
* StickyHeaders:
* Only update class as needed. See [issue #1018](https://github.com/Mottie/tablesorter/issues/1018).
* Check horizontal scrolling. Fixes [issue #1455](https://github.com/Mottie/tablesorter/issues/1455).
* UITheme:
* Remove bootstrap v2 refs &amp; fix docs. See [issue #1432](https://github.com/Mottie/tablesorter/issues/1432).
* Docs:
* Miscellaneous fixes and updates.
* Add more info about zebra widget when the table is not visible. See [PR #1438](https://github.com/Mottie/tablesorter/pull/1438); thanks [@Federico-G](https://github.com/Federico-G)!
* Fix alignCharacter widget reference to css4.
* Update userfrosting link in the readme.
* Update to Bootstrap v4.0.0-beta.
* Fix colspan demo.
* Themes:
* Rename `icon-white` to `bootstrap-icon-white`. Fixes [issue #1432](https://github.com/Mottie/tablesorter/issues/1432).
* Meta:
* Update dependencies.
* Build: maintain ie8 support to fix [issue #1431](https://github.com/Mottie/tablesorter/issues/1431).
#### <a name="v2.28.15">Version 2.28.15</a> (7/4/2017)
* Core:
@ -137,15 +176,3 @@ View the [complete change log here](https://github.com/Mottie/tablesorter/wiki/C
* 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.
#### <a name="v2.28.13">Version 2.28.13</a> (6/2/2017)
* Core:
* Add cssIconDisabled option. See [issue #1409](https://github.com/Mottie/tablesorter/issues/1409).
* Coerce sort natural elements into strings. See [issue #1415](https://github.com/Mottie/tablesorter/issues/1415).
* StickyHeaders:
* Fix dynamic updating of offset. Fixes [issue #1412](https://github.com/Mottie/tablesorter/issues/1412).
* Init with visible headers on partial scroll
* Meta:
* Set jQuery dependency back to >=1.2.6. Fixes [issue #1411](https://github.com/Mottie/tablesorter/issues/1411).
* Add `package-lock.json` file.

2
css/bootstrap.less vendored
View File

@ -1,4 +1,4 @@
/* Tablesorter Custom Bootstrap LESS Theme by Rob Garrison
/* Tablesorter Custom Bootstrap v3 LESS Theme by Rob Garrison
To create your own theme, modify the code below and run it through
a LESS compiler, like this one: http://leafo.net/lessphp/editor.html

View File

@ -56,8 +56,8 @@
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
}
/* white unsorted icon */
.tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
/* white unsorted icon; updated to use bootstrap-icon-white - see #1432 */
.tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
}

View File

@ -53,8 +53,8 @@
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAA20lEQVR4AWJABpKSkoxALCstLb0aUAsZaCAMhVEY6B0amx8YZWDDEDSBa2AGe7XeIiAAClYwVGBvsAcIllsf/mvcC9DgOOd8h90fxWvngVEUbZIkuWRZZlE8eQjcisgZMM9zi+LJ6ZfwegmWZflZDugdHMfxTcGqql7TNBlUB/QObtv2VBSFrev6OY7jngzFk9OT/fn73fWYpqnlXNyXDMWT0zuYx/Bvel9ej+LJ6R08DMOu67q7DkTkrSA5vYPneV71fX/QASdTkJwezhs0TfMARn0wMDDGXEPgF4oijqwM5YjNAAAAAElFTkSuQmCC);
}
/* white unsorted icon */
.tablesorter-bootstrap .icon-white.bootstrap-icon-unsorted {
/* white unsorted icon; updated to use bootstrap-icon-white - see #1432 */
.tablesorter-bootstrap .bootstrap-icon-white.bootstrap-icon-unsorted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAe0lEQVR4AbXQoRWDMBiF0Sh2QLAAQ8SxJGugWSA6A2STW1PxTsnB9cnkfuYvv8OGC1t5G3Y0QMP+Bm857keAdQIzWBP3+Bw4MADQE18B6/etRnCV/w9nnGuLezfAmXhABGtAGIkruvk6auIFRwQJDywllsEAjCecB20GP59BQQ+gtlRLAAAAAElFTkSuQmCC);
}

View File

@ -1,4 +1,4 @@
/* Tablesorter Custom Bootstrap LESS Theme by Rob Garrison
/* Tablesorter Custom Bootstrap v3 LESS Theme by Rob Garrison
To create your own theme, modify the code below and run it through
a LESS compiler, like this one: http://leafo.net/lessphp/editor.html

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/* 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.28.15 *//*
/*! TableSorter (FORK) v2.29.0 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -34,7 +34,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.28.15',
version : '2.29.0',
parsers : [],
widgets : [],
@ -433,10 +433,10 @@
e.stopPropagation();
ts.applyWidgetId( this, id );
})
.bind( 'applyWidgets' + namespace, function( e, init ) {
.bind( 'applyWidgets' + namespace, function( e, callback ) {
e.stopPropagation();
// apply widgets
ts.applyWidget( this, init );
// apply widgets (false = not initializing)
ts.applyWidget( this, false, callback );
})
.bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
e.stopPropagation();
@ -473,9 +473,9 @@
downTarget = null;
if ( core !== true ) {
$headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
$( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
tmp = ts.getClosest( $headers, 'table' );
if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
$( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
}
}
tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@ -527,8 +527,7 @@
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
/TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
$cell = ts.getHeaderCell( $( this ) );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -568,7 +567,7 @@
'';
// 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,
var configHeaders, header, column, template, tmp, $th,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@ -594,7 +593,9 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
column = parseInt( $elem.attr( 'data-column' ), 10 );
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.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
@ -612,10 +613,9 @@
}
// add cell to headerList
c.headerList[ index ] = elem;
$elem.addClass( ts.css.header + ' ' + c.cssHeader );
// add to parent in case there are multiple rows
$elem
.addClass( ts.css.header + ' ' + c.cssHeader )
.parent()
ts.getClosest( $elem, 'tr' )
.addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
.attr( 'role', 'row' );
// allow keyboard cursor to focus on element
@ -1173,10 +1173,29 @@
}
},
// 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 /TH|TD/.test( $el[0].nodeName ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var column = parseInt( $header.attr( 'data-column' ), 10 ),
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1334,10 +1353,9 @@
$cell = $( cell ),
// update cache - format: function( s, table, cell, cellIndex )
// no closest in jQuery v1.2.6
tbodyIndex = $tbodies
.index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
tbcache = c.cache[ tbodyIndex ],
$row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
$row = ts.getClosest( $cell, 'tr' );
cell = $cell[ 0 ]; // in case cell is a jQuery object
// tbody may not exist if update is initialized while tbody is removed for processing
if ( $tbodies.length && tbodyIndex >= 0 ) {
@ -1392,11 +1410,13 @@
if ( valid ) {
$row = $( $row );
c.$tbodies.append( $row );
} else if ( !$row ||
} else if (
!$row ||
// row is a jQuery object?
!( $row instanceof jQuery ) ||
// row contained in the table?
( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
) {
if ( c.debug ) {
console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@ -1543,10 +1563,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index
col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -2070,7 +2090,7 @@
if ( !widget.priority ) { widget.priority = 10; }
widgets[ indx ] = widget;
} else if ( c.debug ) {
console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
}
}
// sort widgets by priority
@ -2142,6 +2162,7 @@
c.widgetInit[ name[ index ] ] = false;
}
}
c.$table.triggerHandler( 'widgetRemoveEnd', table );
},
refreshWidgets : function( table, doAll, dontapply ) {
@ -2993,7 +3014,7 @@
})(jQuery, window, document);
/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
@ -3010,10 +3031,10 @@
active : '', // applied when column is sorted
hover : '', // custom css required - a defined bootstrap style may not override other classes
// icon class names
icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
filterRow : '', // filter row class
footerRow : '',
footerCells : '',
@ -5196,7 +5217,7 @@
})( jQuery );
/*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.4.3+
* by Rob Garrison
*/
@ -5348,10 +5369,14 @@
});
}
},
getLeftPosition = function() {
return $attach.length ?
parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
},
resizeHeader = function() {
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
left : getLeftPosition(),
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
@ -5361,10 +5386,10 @@
if (!$table.is(':visible')) { return; } // fixes #278
// Detect nested tables - fixes #724
nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
var offset = $table.offset(),
var tmp,
offset = $table.offset(),
stickyOffset = getStickyOffset(c, wo),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
attachTop = $attach.length ?
( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
$yScroll.scrollTop(),
@ -5372,19 +5397,27 @@
scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
needsUpdating = !$stickyWrap.hasClass( state ),
cssSettings = { visibility : isVisible };
if ($attach.length) {
// attached sticky headers always need updating
needsUpdating = true;
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
}
if (xWindow) {
// adjust when scrolling horizontally - fixes issue #143
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
tmp = getLeftPosition();
if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
needsUpdating = true;
cssSettings.left = tmp;
}
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
if (needsUpdating) {
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.addClass( state )
.css(cssSettings);
}
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();
@ -5503,7 +5536,7 @@
})(jQuery, window);
/*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
/*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
/*jshint browser:true, jquery:true, unused:false */
;(function ($, window) {
'use strict';
@ -5830,6 +5863,7 @@
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.triggerHandler('stickyHeadersUpdate');
c.$table.triggerHandler('resizableComplete');
}
};

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@
}
}(function(jQuery) {
/*! TableSorter (FORK) v2.28.15 *//*
/*! TableSorter (FORK) v2.29.0 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -32,7 +32,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.28.15',
version : '2.29.0',
parsers : [],
widgets : [],
@ -431,10 +431,10 @@
e.stopPropagation();
ts.applyWidgetId( this, id );
})
.bind( 'applyWidgets' + namespace, function( e, init ) {
.bind( 'applyWidgets' + namespace, function( e, callback ) {
e.stopPropagation();
// apply widgets
ts.applyWidget( this, init );
// apply widgets (false = not initializing)
ts.applyWidget( this, false, callback );
})
.bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
e.stopPropagation();
@ -471,9 +471,9 @@
downTarget = null;
if ( core !== true ) {
$headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
$( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
tmp = ts.getClosest( $headers, 'table' );
if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
$( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
}
}
tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@ -525,8 +525,7 @@
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
/TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
$cell = ts.getHeaderCell( $( this ) );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -566,7 +565,7 @@
'';
// 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,
var configHeaders, header, column, template, tmp, $th,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@ -592,7 +591,9 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
column = parseInt( $elem.attr( 'data-column' ), 10 );
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.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
@ -610,10 +611,9 @@
}
// add cell to headerList
c.headerList[ index ] = elem;
$elem.addClass( ts.css.header + ' ' + c.cssHeader );
// add to parent in case there are multiple rows
$elem
.addClass( ts.css.header + ' ' + c.cssHeader )
.parent()
ts.getClosest( $elem, 'tr' )
.addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
.attr( 'role', 'row' );
// allow keyboard cursor to focus on element
@ -1171,10 +1171,29 @@
}
},
// 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 /TH|TD/.test( $el[0].nodeName ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var column = parseInt( $header.attr( 'data-column' ), 10 ),
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1332,10 +1351,9 @@
$cell = $( cell ),
// update cache - format: function( s, table, cell, cellIndex )
// no closest in jQuery v1.2.6
tbodyIndex = $tbodies
.index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
tbcache = c.cache[ tbodyIndex ],
$row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
$row = ts.getClosest( $cell, 'tr' );
cell = $cell[ 0 ]; // in case cell is a jQuery object
// tbody may not exist if update is initialized while tbody is removed for processing
if ( $tbodies.length && tbodyIndex >= 0 ) {
@ -1390,11 +1408,13 @@
if ( valid ) {
$row = $( $row );
c.$tbodies.append( $row );
} else if ( !$row ||
} else if (
!$row ||
// row is a jQuery object?
!( $row instanceof jQuery ) ||
// row contained in the table?
( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
) {
if ( c.debug ) {
console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@ -1541,10 +1561,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index
col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -2068,7 +2088,7 @@
if ( !widget.priority ) { widget.priority = 10; }
widgets[ indx ] = widget;
} else if ( c.debug ) {
console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
}
}
// sort widgets by priority
@ -2140,6 +2160,7 @@
c.widgetInit[ name[ index ] ] = false;
}
}
c.$table.triggerHandler( 'widgetRemoveEnd', table );
},
refreshWidgets : function( table, doAll, dontapply ) {

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
/*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -127,7 +127,7 @@
})(jQuery, window, document);
/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
@ -144,10 +144,10 @@
active : '', // applied when column is sorted
hover : '', // custom css required - a defined bootstrap style may not override other classes
// icon class names
icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
filterRow : '', // filter row class
footerRow : '',
footerCells : '',
@ -2330,7 +2330,7 @@
})( jQuery );
/*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.4.3+
* by Rob Garrison
*/
@ -2482,10 +2482,14 @@
});
}
},
getLeftPosition = function() {
return $attach.length ?
parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
},
resizeHeader = function() {
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
left : getLeftPosition(),
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
@ -2495,10 +2499,10 @@
if (!$table.is(':visible')) { return; } // fixes #278
// Detect nested tables - fixes #724
nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
var offset = $table.offset(),
var tmp,
offset = $table.offset(),
stickyOffset = getStickyOffset(c, wo),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
attachTop = $attach.length ?
( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
$yScroll.scrollTop(),
@ -2506,19 +2510,27 @@
scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
needsUpdating = !$stickyWrap.hasClass( state ),
cssSettings = { visibility : isVisible };
if ($attach.length) {
// attached sticky headers always need updating
needsUpdating = true;
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
}
if (xWindow) {
// adjust when scrolling horizontally - fixes issue #143
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
tmp = getLeftPosition();
if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
needsUpdating = true;
cssSettings.left = tmp;
}
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
if (needsUpdating) {
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.addClass( state )
.css(cssSettings);
}
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();
@ -2637,7 +2649,7 @@
})(jQuery, window);
/*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
/*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
/*jshint browser:true, jquery:true, unused:false */
;(function ($, window) {
'use strict';
@ -2964,6 +2976,7 @@
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.triggerHandler('stickyHeadersUpdate');
c.$table.triggerHandler('resizableComplete');
}
};

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! Widget: sort2Hash (BETA) - updated 7/4/2017 (v2.28.15) */
!function(e){"use strict";var t=e.tablesorter||{},a=t.sort2Hash={init:function(r,o){var s,n,i,h,d=r.table,l=r.pager,c=t.hasWidget(d,"saveSort"),H=a.decodeHash(r,o,"sort");(H&&!c||H&&c&&o.sort2Hash_overrideSaveSort)&&a.convertString2Sort(r,o,H),t.hasWidget(r.table,"pager")&&(n=parseInt(a.decodeHash(r,o,"page"),10),i=l.page=n<0?0:n>l.totalPages?l.totalPages-1:n,h=l.size=parseInt(a.decodeHash(r,o,"size"),10)),t.hasWidget(d,"filter")&&(s=a.decodeHash(r,o,"filter"))&&(s=s.split(o.sort2Hash_separator),r.$table.one("tablesorter-ready",function(){setTimeout(function(){r.$table.one("filterEnd",function(){e(this).triggerHandler("pageAndSize",[i,h])}),(n=t.filter.equalFilters?t.filter.equalFilters(r,r.lastSearch,s):(r.lastSearch||[]).join("")!==(s||[]).join(""))||e.tablesorter.setFilters(d,s,!0)},100)})),s||r.$table.one("tablesorter-ready",function(){r.$table.triggerHandler("pageAndSize",[i,h])}),r.$table.on("sortEnd.sort2hash filterEnd.sort2hash pagerComplete.sort2Hash",function(){this.hasInitialized&&a.setHash(this.config,this.config.widgetOptions)})},getTableId:function(t,a){return a.sort2Hash_tableId||t.table.id||"table"+e("table").index(t.$table)},regexEscape:function(e){return e.replace(/([\.\^\$\*\+\-\?\(\)\[\]\{\}\\\|])/g,"\\$1")},convertString2Sort:function(e,t,r){for(var o,s,n,i,h,d,l=r.split(t.sort2Hash_separator),c=0,H=l.length,g=[];c<H;){if(s=l[c++],i=parseInt(s,10),isNaN(i)||i>e.columns)for(o=new RegExp("("+a.regexEscape(s)+")","i"),h=0;h<e.columns;h++)d=e.$headerIndexed[h],o.test(d.attr(t.sort2Hash_headerTextAttr))&&(s=h,h=e.columns);n=l[c++],void 0!==s&&void 0!==n&&(isNaN(n)&&(n=n.indexOf(t.sort2Hash_directionText[1])>-1?1:0),g.push([s,n]))}g.length&&(e.sortList=g)},convertSort2String:function(t,a){var r,o,s,n,i=[],h=t.sortList||[],d=h.length;for(r=0;r<d;r++)s=h[r][0],o=e.trim(t.$headerIndexed[s].attr(a.sort2Hash_headerTextAttr)),i.push(""!==o?encodeURIComponent(o):s),n=a.sort2Hash_directionText[h[r][1]],i.push(n);return i.join(a.sort2Hash_separator)},convertFilter2String:function(t,a){var r,o,s,n,i=[],h=t.sortList||[],d=h.length;for(r=0;r<d;r++)s=h[r][0],s=void 0!==(o=e.trim(t.$headerIndexed[s].attr(a.sort2Hash_headerTextAttr)))?encodeURIComponent(o):s,i.push(s),n=a.sort2Hash_directionText[h[r][1]],i.push(n);return i.join(a.sort2Hash_separator)},getParam:function(e,t,r){t||(t=window.location.hash);var o=new RegExp("[\\?&]"+a.regexEscape(e)+"=([^&#]*)"),s=o.exec(t);return r?o:null===s?"":decodeURIComponent(s[1])},removeParam:function(e,t){t||(t=window.location.hash);var r,o=a.getParam(e,t,!0),s=[],n=t.split("&"),i=n.length;for(r=0;r<i;r++)o.test("&"+n[r])||s.push(n[r]);return s.length?s.join("&"):""},encodeHash:function(e,t,r,o,s){var n=!1,i=a.getTableId(e,t);return"function"==typeof t.sort2Hash_encodeHash&&(n=t.sort2Hash_encodeHash(e,i,r,o,s||o)),!1===n&&(n="&"+r+"["+i+"]="+o),n},decodeHash:function(e,t,r){var o=!1,s=a.getTableId(e,t);return"function"==typeof t.sort2Hash_decodeHash&&(o=t.sort2Hash_decodeHash(e,s,r)),!1===o&&(o=a.getParam(r+"["+s+"]")),o||""},cleanHash:function(e,t,r,o){var s=!1,n=a.getTableId(e,t);return"function"==typeof t.sort2Hash_cleanHash&&(s=t.sort2Hash_cleanHash(e,n,r,o)),!1===s&&(s=a.removeParam(r+"["+n+"]",o)),s||""},setHash:function(r,o){var s="",n=window.location.hash,i=t.hasWidget(r.table,"pager"),h=t.hasWidget(r.table,"filter"),d=a.convertSort2String(r,o),l=h&&""!==r.lastSearch.join("")?r.lastSearch:[],c=encodeURIComponent(l.join(r.widgetOptions.sort2Hash_separator)),H={sort:d?a.encodeHash(r,o,"sort",d,r.sortList):"",page:i?a.encodeHash(r,o,"page",r.pager.page+1):"",size:i?a.encodeHash(r,o,"size",r.pager.size):"",filter:c?a.encodeHash(r,o,"filter",c,l):""};e.each(H,function(e,t){n=a.cleanHash(r,o,e,n),s+=t}),window.location.hash=((window.location.hash||"").replace("#","").length?n:o.sort2Hash_hash)+s}};t.addWidget({id:"sort2Hash",priority:60,options:{sort2Hash_hash:"#",sort2Hash_separator:"-",sort2Hash_headerTextAttr:"data-header",sort2Hash_directionText:[0,1],sort2Hash_overrideSaveSort:!1,sort2Hash_tableId:null,sort2Hash_encodeHash:null,sort2Hash_decodeHash:null,sort2Hash_cleanHash:null},init:function(e,t,r,o){a.init(r,o)},remove:function(e,t){t.$table.off(".sort2hash")}})}(jQuery);
/*! Widget: sort2Hash (BETA) - updated 9/27/2017 (v2.29.0) */
!function(e){"use strict";var t=e.tablesorter||{},a=t.sort2Hash={init:function(r,o){var s,n,i,h,l=r.table,d=r.pager,c=t.hasWidget(l,"saveSort"),H=a.decodeHash(r,o,"sort");(H&&!c||H&&c&&o.sort2Hash_overrideSaveSort)&&a.convertString2Sort(r,o,H),t.hasWidget(r.table,"pager")&&(n=parseInt(a.decodeHash(r,o,"page"),10),i=d.page=n<0?0:n>d.totalPages?d.totalPages-1:n,h=d.size=parseInt(a.decodeHash(r,o,"size"),10)),t.hasWidget(l,"filter")&&(s=a.decodeHash(r,o,"filter"))&&(s=s.split(o.sort2Hash_separator),r.$table.one("tablesorter-ready",function(){setTimeout(function(){r.$table.one("filterEnd",function(){e(this).triggerHandler("pageAndSize",[i,h])}),(n=t.filter.equalFilters?t.filter.equalFilters(r,r.lastSearch,s):(r.lastSearch||[]).join("")!==(s||[]).join(""))||e.tablesorter.setFilters(l,s,!0)},100)})),s||r.$table.one("tablesorter-ready",function(){r.$table.triggerHandler("pageAndSize",[i,h])}),r.$table.on("sortEnd.sort2hash filterEnd.sort2hash pagerComplete.sort2Hash",function(){this.hasInitialized&&a.setHash(this.config,this.config.widgetOptions)})},getTableId:function(t,a){return a.sort2Hash_tableId||t.table.id||"table"+e("table").index(t.$table)},regexEscape:function(e){return e.replace(/([\.\^\$\*\+\-\?\(\)\[\]\{\}\\\|])/g,"\\$1")},convertString2Sort:function(e,t,r){for(var o,s,n,i,h,l,d=r.split(t.sort2Hash_separator),c=0,H=d.length,g=[];c<H;){if(s=d[c++],i=parseInt(s,10),isNaN(i)||i>e.columns)for(o=new RegExp("("+a.regexEscape(s)+")","i"),h=0;h<e.columns;h++)l=e.$headerIndexed[h],o.test(l.attr(t.sort2Hash_headerTextAttr))&&(s=h,h=e.columns);n=d[c++],void 0!==s&&void 0!==n&&(isNaN(n)&&(n=n.indexOf(t.sort2Hash_directionText[1])>-1?1:0),g.push([s,n]))}g.length&&(e.sortList=g)},convertSort2String:function(t,a){var r,o,s,n,i=[],h=t.sortList||[],l=h.length;for(r=0;r<l;r++)s=h[r][0],o=e.trim(t.$headerIndexed[s].attr(a.sort2Hash_headerTextAttr)),i.push(""!==o?encodeURIComponent(o):s),n=a.sort2Hash_directionText[h[r][1]],i.push(n);return i.join(a.sort2Hash_separator)},convertFilter2String:function(t,a){var r,o,s,n,i=[],h=t.sortList||[],l=h.length;for(r=0;r<l;r++)s=h[r][0],s=void 0!==(o=e.trim(t.$headerIndexed[s].attr(a.sort2Hash_headerTextAttr)))?encodeURIComponent(o):s,i.push(s),n=a.sort2Hash_directionText[h[r][1]],i.push(n);return i.join(a.sort2Hash_separator)},getParam:function(e,t,r){t||(t=window.location.hash);var o=new RegExp("[\\?&]"+a.regexEscape(e)+"=([^&#]*)"),s=o.exec(t);return r?o:null===s?"":decodeURIComponent(s[1])},removeParam:function(e,t){t||(t=window.location.hash);var r,o=a.getParam(e,t,!0),s=[],n=t.split("&"),i=n.length;for(r=0;r<i;r++)o.test("&"+n[r])||s.push(n[r]);return s.length?s.join("&"):""},encodeHash:function(e,t,r,o,s){var n=!1,i=a.getTableId(e,t);return"function"==typeof t.sort2Hash_encodeHash&&(n=t.sort2Hash_encodeHash(e,i,r,o,s||o)),!1===n&&(n="&"+r+"["+i+"]="+o),n},decodeHash:function(e,t,r){var o=!1,s=a.getTableId(e,t);return"function"==typeof t.sort2Hash_decodeHash&&(o=t.sort2Hash_decodeHash(e,s,r)),!1===o&&(o=a.getParam(r+"["+s+"]")),o||""},cleanHash:function(e,t,r,o){var s=!1,n=a.getTableId(e,t);return"function"==typeof t.sort2Hash_cleanHash&&(s=t.sort2Hash_cleanHash(e,n,r,o)),!1===s&&(s=a.removeParam(r+"["+n+"]",o)),s||""},setHash:function(r,o){var s="",n=window.location.hash,i=t.hasWidget(r.table,"pager"),h=t.hasWidget(r.table,"filter"),l=a.convertSort2String(r,o),d=h&&""!==r.lastSearch.join("")?r.lastSearch:[],c=encodeURIComponent(d.join(r.widgetOptions.sort2Hash_separator)),H={sort:l?a.encodeHash(r,o,"sort",l,r.sortList):"",page:i?a.encodeHash(r,o,"page",r.pager.page+1):"",size:i?a.encodeHash(r,o,"size",r.pager.size):"",filter:c?a.encodeHash(r,o,"filter",c,d):""};e.each(H,function(e,t){n=a.cleanHash(r,o,e,n),s+=t});var g=o.sort2Hash_hash,p=((window.location.hash||"").replace(g,"").length?n:g)+s;if(o.sort2Hash_replaceHistory){var u=window.location.href.split(g)[0];p[0]!=g&&(p=g+p),window.location.replace(u+p)}else window.location.hash=p}};t.addWidget({id:"sort2Hash",priority:60,options:{sort2Hash_hash:"#",sort2Hash_separator:"-",sort2Hash_headerTextAttr:"data-header",sort2Hash_directionText:[0,1],sort2Hash_overrideSaveSort:!1,sort2Hash_replaceHistory:!1,sort2Hash_tableId:null,sort2Hash_encodeHash:null,sort2Hash_decodeHash:null,sort2Hash_cleanHash:null},init:function(e,t,r,o){a.init(r,o)},remove:function(e,t){t.$table.off(".sort2hash")}})}(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
!function(e){"use strict";var o=e.tablesorter||{};o.themes={bootstrap:{table:"table table-bordered table-striped",caption:"caption",header:"bootstrap-header",sortNone:"",sortAsc:"",sortDesc:"",active:"",hover:"",icons:"",iconSortNone:"bootstrap-icon-unsorted",iconSortAsc:"icon-chevron-up glyphicon glyphicon-chevron-up",iconSortDesc:"icon-chevron-down glyphicon glyphicon-chevron-down",filterRow:"",footerRow:"",footerCells:"",even:"",odd:""},jui:{table:"ui-widget ui-widget-content ui-corner-all",caption:"ui-widget-content",header:"ui-widget-header ui-corner-all ui-state-default",sortNone:"",sortAsc:"",sortDesc:"",active:"ui-state-active",hover:"ui-state-hover",icons:"ui-icon",iconSortNone:"ui-icon-carat-2-n-s ui-icon-caret-2-n-s",iconSortAsc:"ui-icon-carat-1-n ui-icon-caret-1-n",iconSortDesc:"ui-icon-carat-1-s ui-icon-caret-1-s",filterRow:"",footerRow:"",footerCells:"",even:"ui-widget-content",odd:"ui-state-default"}},e.extend(o.css,{wrapper:"tablesorter-wrapper"}),o.addWidget({id:"uitheme",priority:10,format:function(t,s,r){var i,a,n,c,l,d,h,m,u,p,v,f,b,C=o.themes,w=s.$table.add(e(s.namespace+"_extra_table")),g=s.$headers.add(e(s.namespace+"_extra_headers")),S=s.theme||"jui",j=C[S]||{},D=e.trim([j.sortNone,j.sortDesc,j.sortAsc,j.active].join(" ")),A=e.trim([j.iconSortNone,j.iconSortDesc,j.iconSortAsc].join(" "));for(s.debug&&(l=new Date),w.hasClass("tablesorter-"+S)&&s.theme===s.appliedTheme&&r.uitheme_applied||(r.uitheme_applied=!0,p=C[s.appliedTheme]||{},v=(b=!e.isEmptyObject(p))?[p.sortNone,p.sortDesc,p.sortAsc,p.active].join(" "):"",f=b?[p.iconSortNone,p.iconSortDesc,p.iconSortAsc].join(" "):"",b&&(r.zebra[0]=e.trim(" "+r.zebra[0].replace(" "+p.even,"")),r.zebra[1]=e.trim(" "+r.zebra[1].replace(" "+p.odd,"")),s.$tbodies.children().removeClass([p.even,p.odd].join(" "))),j.even&&(r.zebra[0]+=" "+j.even),j.odd&&(r.zebra[1]+=" "+j.odd),w.children("caption").removeClass(p.caption||"").addClass(j.caption),m=w.removeClass((s.appliedTheme?"tablesorter-"+(s.appliedTheme||""):"")+" "+(p.table||"")).addClass("tablesorter-"+S+" "+(j.table||"")).children("tfoot"),s.appliedTheme=s.theme,m.length&&m.children("tr").removeClass(p.footerRow||"").addClass(j.footerRow).children("th, td").removeClass(p.footerCells||"").addClass(j.footerCells),g.removeClass((b?[p.header,p.hover,v].join(" "):"")||"").addClass(j.header).not(".sorter-false").unbind("mouseenter.tsuitheme mouseleave.tsuitheme").bind("mouseenter.tsuitheme mouseleave.tsuitheme",function(o){e(this)["mouseenter"===o.type?"addClass":"removeClass"](j.hover||"")}),g.each(function(){var t=e(this);t.find("."+o.css.wrapper).length||t.wrapInner('<div class="'+o.css.wrapper+'" style="position:relative;height:100%;width:100%"></div>')}),s.cssIcon&&g.find("."+o.css.icon).removeClass(b?[p.icons,f].join(" "):"").addClass(j.icons||""),o.hasWidget(s.table,"filter")&&(a=function(){w.children("thead").children("."+o.css.filterRow).removeClass(b?p.filterRow||"":"").addClass(j.filterRow||"")},r.filter_initialized?a():w.one("filterInit",function(){a()}))),i=0;i<s.columns;i++)d=s.$headers.add(e(s.namespace+"_extra_headers")).not(".sorter-false").filter('[data-column="'+i+'"]'),h=o.css.icon?d.find("."+o.css.icon):e(),(u=g.not(".sorter-false").filter('[data-column="'+i+'"]:last')).length&&(d.removeClass(D),h.removeClass(A),u[0].sortDisabled?h.removeClass(j.icons||""):(n=j.sortNone,c=j.iconSortNone,u.hasClass(o.css.sortAsc)?(n=[j.sortAsc,j.active].join(" "),c=j.iconSortAsc):u.hasClass(o.css.sortDesc)&&(n=[j.sortDesc,j.active].join(" "),c=j.iconSortDesc),d.addClass(n),h.addClass(c||"")));s.debug&&console.log("Applying "+S+" theme"+o.benchmark(l))},remove:function(e,t,s,r){if(s.uitheme_applied){var i=t.$table,a=t.appliedTheme||"jui",n=o.themes[a]||o.themes.jui,c=i.children("thead").children(),l=n.sortNone+" "+n.sortDesc+" "+n.sortAsc,d=n.iconSortNone+" "+n.iconSortDesc+" "+n.iconSortAsc;i.removeClass("tablesorter-"+a+" "+n.table),s.uitheme_applied=!1,r||(i.find(o.css.header).removeClass(n.header),c.unbind("mouseenter.tsuitheme mouseleave.tsuitheme").removeClass(n.hover+" "+l+" "+n.active).filter("."+o.css.filterRow).removeClass(n.filterRow),c.find("."+o.css.icon).removeClass(n.icons+" "+d))}}})}(jQuery);
/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
!function(e){"use strict";var o=e.tablesorter||{};o.themes={bootstrap:{table:"table table-bordered table-striped",caption:"caption",header:"bootstrap-header",sortNone:"",sortAsc:"",sortDesc:"",active:"",hover:"",icons:"",iconSortNone:"bootstrap-icon-unsorted",iconSortAsc:"glyphicon glyphicon-chevron-up",iconSortDesc:"glyphicon glyphicon-chevron-down",filterRow:"",footerRow:"",footerCells:"",even:"",odd:""},jui:{table:"ui-widget ui-widget-content ui-corner-all",caption:"ui-widget-content",header:"ui-widget-header ui-corner-all ui-state-default",sortNone:"",sortAsc:"",sortDesc:"",active:"ui-state-active",hover:"ui-state-hover",icons:"ui-icon",iconSortNone:"ui-icon-carat-2-n-s ui-icon-caret-2-n-s",iconSortAsc:"ui-icon-carat-1-n ui-icon-caret-1-n",iconSortDesc:"ui-icon-carat-1-s ui-icon-caret-1-s",filterRow:"",footerRow:"",footerCells:"",even:"ui-widget-content",odd:"ui-state-default"}},e.extend(o.css,{wrapper:"tablesorter-wrapper"}),o.addWidget({id:"uitheme",priority:10,format:function(t,s,r){var i,a,n,c,l,d,h,m,u,p,v,f,b,C=o.themes,w=s.$table.add(e(s.namespace+"_extra_table")),g=s.$headers.add(e(s.namespace+"_extra_headers")),S=s.theme||"jui",j=C[S]||{},D=e.trim([j.sortNone,j.sortDesc,j.sortAsc,j.active].join(" ")),A=e.trim([j.iconSortNone,j.iconSortDesc,j.iconSortAsc].join(" "));for(s.debug&&(l=new Date),w.hasClass("tablesorter-"+S)&&s.theme===s.appliedTheme&&r.uitheme_applied||(r.uitheme_applied=!0,p=C[s.appliedTheme]||{},v=(b=!e.isEmptyObject(p))?[p.sortNone,p.sortDesc,p.sortAsc,p.active].join(" "):"",f=b?[p.iconSortNone,p.iconSortDesc,p.iconSortAsc].join(" "):"",b&&(r.zebra[0]=e.trim(" "+r.zebra[0].replace(" "+p.even,"")),r.zebra[1]=e.trim(" "+r.zebra[1].replace(" "+p.odd,"")),s.$tbodies.children().removeClass([p.even,p.odd].join(" "))),j.even&&(r.zebra[0]+=" "+j.even),j.odd&&(r.zebra[1]+=" "+j.odd),w.children("caption").removeClass(p.caption||"").addClass(j.caption),m=w.removeClass((s.appliedTheme?"tablesorter-"+(s.appliedTheme||""):"")+" "+(p.table||"")).addClass("tablesorter-"+S+" "+(j.table||"")).children("tfoot"),s.appliedTheme=s.theme,m.length&&m.children("tr").removeClass(p.footerRow||"").addClass(j.footerRow).children("th, td").removeClass(p.footerCells||"").addClass(j.footerCells),g.removeClass((b?[p.header,p.hover,v].join(" "):"")||"").addClass(j.header).not(".sorter-false").unbind("mouseenter.tsuitheme mouseleave.tsuitheme").bind("mouseenter.tsuitheme mouseleave.tsuitheme",function(o){e(this)["mouseenter"===o.type?"addClass":"removeClass"](j.hover||"")}),g.each(function(){var t=e(this);t.find("."+o.css.wrapper).length||t.wrapInner('<div class="'+o.css.wrapper+'" style="position:relative;height:100%;width:100%"></div>')}),s.cssIcon&&g.find("."+o.css.icon).removeClass(b?[p.icons,f].join(" "):"").addClass(j.icons||""),o.hasWidget(s.table,"filter")&&(a=function(){w.children("thead").children("."+o.css.filterRow).removeClass(b?p.filterRow||"":"").addClass(j.filterRow||"")},r.filter_initialized?a():w.one("filterInit",function(){a()}))),i=0;i<s.columns;i++)d=s.$headers.add(e(s.namespace+"_extra_headers")).not(".sorter-false").filter('[data-column="'+i+'"]'),h=o.css.icon?d.find("."+o.css.icon):e(),(u=g.not(".sorter-false").filter('[data-column="'+i+'"]:last')).length&&(d.removeClass(D),h.removeClass(A),u[0].sortDisabled?h.removeClass(j.icons||""):(n=j.sortNone,c=j.iconSortNone,u.hasClass(o.css.sortAsc)?(n=[j.sortAsc,j.active].join(" "),c=j.iconSortAsc):u.hasClass(o.css.sortDesc)&&(n=[j.sortDesc,j.active].join(" "),c=j.iconSortDesc),d.addClass(n),h.addClass(c||"")));s.debug&&console.log("Applying "+S+" theme"+o.benchmark(l))},remove:function(e,t,s,r){if(s.uitheme_applied){var i=t.$table,a=t.appliedTheme||"jui",n=o.themes[a]||o.themes.jui,c=i.children("thead").children(),l=n.sortNone+" "+n.sortDesc+" "+n.sortAsc,d=n.iconSortNone+" "+n.iconSortDesc+" "+n.iconSortAsc;i.removeClass("tablesorter-"+a+" "+n.table),s.uitheme_applied=!1,r||(i.find(o.css.header).removeClass(n.header),c.unbind("mouseenter.tsuitheme mouseleave.tsuitheme").removeClass(n.hover+" "+l+" "+n.active).filter("."+o.css.filterRow).removeClass(n.filterRow),c.find("."+o.css.icon).removeClass(n.icons+" "+d))}}})}(jQuery);

View File

@ -1 +1 @@
!function(e){"use strict";var t,i,a,o=e.tablesorter,n=!1,l=o.view={copyCaption:function(t,i){l.removeCaption(t,i),t.$table.find("caption").length>0&&e(i.view_caption).text(t.$table.find("caption").text())},removeCaption:function(t,i){e(i.view_caption).empty()},buildToolBar:function(t,i){l.removeToolBar(t,i),l.copyCaption(t,i);var a=e(i.view_toolbar);e.each(i.view_layouts,function(t,o){var n=i.view_switcher_class;t==i.view_layout&&(n+=" active");var l=e("<a>",{href:"#",class:n,"data-view-type":t,title:o.title});l.append(e("<i>",{class:o.icon})),a.append(l)}),a.find("."+i.view_switcher_class).on("click",function(o){if(o.preventDefault(),e(this).hasClass("active"))return!1;a.find("."+i.view_switcher_class).removeClass("active"),e(this).addClass("active"),i.view_layout=e(this).attr("data-view-type"),!0===i.view_layouts[i.view_layout].raw?(l.remove(t,i),l.buildToolBar(t,i)):(!1===n&&l.hideTable(t,i),l.buildView(t,i))})},removeToolBar:function(t,i){e(i.view_toolbar).empty(),l.removeCaption(t,i)},buildView:function(t,i){l.removeView(t,i);var a=i.view_layouts[i.view_layout],n=e(a.container,{class:i.view_layout});o.getColumnText(t.$table,0,function(t){var i=a.tmpl;e.each(e(t.$row).find("td"),function(t,a){var o={},n="{col"+t+"}";e.each(a.attributes,function(e,t){o[t.nodeName]=t.nodeValue});var l=e(a).html(),r=e("<span />").append(e("<span/>",o).append(l));i=i.replace(new RegExp(n,"g"),r.html()),n="{col"+t+":raw}",i=i.replace(new RegExp(n,"g"),e(a).text())});var o=e(i);e.each(t.$row[0].attributes,function(e,t){"class"==t.nodeName?o.attr(t.nodeName,o.attr(t.nodeName)+" "+t.nodeValue):o.attr(t.nodeName,t.nodeValue)}),n.append(o)}),e(i.view_container).append(n),t.$table.triggerHandler("viewComplete")},removeView:function(t,i){e(i.view_container).empty()},hideTable:function(e,o){t=e.$table.css("position"),i=e.$table.css("bottom"),a=e.$table.css("left"),e.$table.css({position:"absolute",top:"-10000px",left:"-10000px"}),n=!0},init:function(e,t){!1!==t.view_layout&&void 0!==t.view_layouts[t.view_layout]&&(!1===n&&l.hideTable(e,t),e.$table.on("tablesorter-ready",function(){l.buildToolBar(e,t),l.buildView(e,t)}))},remove:function(e,o){l.removeToolBar(e,o),l.removeView(e,o),e.$table.css({position:t,top:i,left:a}),n=!1}};o.addWidget({id:"view",options:{view_toolbar:"#ts-view-toolbar",view_container:"#ts-view",view_caption:"#ts-view-caption",view_switcher_class:"ts-view-switcher",view_layout:!1,view_layouts:{}},init:function(e,t,i,a){l.init(i,a)},remove:function(e,t,i){l.remove(t,i)}})}(jQuery);
!function(e){"use strict";var t,i,a,o=e.tablesorter,n=!1,l=o.view={copyCaption:function(t,i){l.removeCaption(t,i),t.$table.find("caption").length>0&&e(i.view_caption).text(t.$table.find("caption").text())},removeCaption:function(t,i){e(i.view_caption).empty()},buildToolBar:function(t,i){l.removeToolBar(t,i),l.copyCaption(t,i);var a=e(i.view_toolbar);e.each(i.view_layouts,function(t,o){var n=i.view_switcher_class;t==i.view_layout&&(n+=" active");var l=e("<a>",{href:"#","class":n,"data-view-type":t,title:o.title});l.append(e("<i>",{"class":o.icon})),a.append(l)}),a.find("."+i.view_switcher_class).on("click",function(o){if(o.preventDefault(),e(this).hasClass("active"))return!1;a.find("."+i.view_switcher_class).removeClass("active"),e(this).addClass("active"),i.view_layout=e(this).attr("data-view-type"),!0===i.view_layouts[i.view_layout].raw?(l.remove(t,i),l.buildToolBar(t,i)):(!1===n&&l.hideTable(t,i),l.buildView(t,i))})},removeToolBar:function(t,i){e(i.view_toolbar).empty(),l.removeCaption(t,i)},buildView:function(t,i){l.removeView(t,i);var a=i.view_layouts[i.view_layout],n=e(a.container,{"class":i.view_layout});o.getColumnText(t.$table,0,function(t){var i=a.tmpl;e.each(e(t.$row).find("td"),function(t,a){var o={},n="{col"+t+"}";e.each(a.attributes,function(e,t){o[t.nodeName]=t.nodeValue});var l=e(a).html(),r=e("<span />").append(e("<span/>",o).append(l));i=i.replace(new RegExp(n,"g"),r.html()),n="{col"+t+":raw}",i=i.replace(new RegExp(n,"g"),e(a).text())});var o=e(i);e.each(t.$row[0].attributes,function(e,t){"class"==t.nodeName?o.attr(t.nodeName,o.attr(t.nodeName)+" "+t.nodeValue):o.attr(t.nodeName,t.nodeValue)}),n.append(o)}),e(i.view_container).append(n),t.$table.triggerHandler("viewComplete")},removeView:function(t,i){e(i.view_container).empty()},hideTable:function(e,o){t=e.$table.css("position"),i=e.$table.css("bottom"),a=e.$table.css("left"),e.$table.css({position:"absolute",top:"-10000px",left:"-10000px"}),n=!0},init:function(e,t){!1!==t.view_layout&&void 0!==t.view_layouts[t.view_layout]&&(!1===n&&l.hideTable(e,t),e.$table.on("tablesorter-ready",function(){l.buildToolBar(e,t),l.buildView(e,t)}))},remove:function(e,o){l.removeToolBar(e,o),l.removeView(e,o),e.$table.css({position:t,top:i,left:a}),n=!1}};o.addWidget({id:"view",options:{view_toolbar:"#ts-view-toolbar",view_container:"#ts-view",view_caption:"#ts-view-caption",view_switcher_class:"ts-view-switcher",view_layout:!1,view_layouts:{}},init:function(e,t,i,a){l.init(i,a)},remove:function(e,t,i){l.remove(t,i)}})}(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -83,7 +83,8 @@
<li>Having a <code>colspan</code> in the tbody is not fully supported by all widgets, and there are still some minor issues to work out.</li>
<li><span class="label alert">Alert</span> Cells with a <code>rowspan</code> are <em>not</em> currently supported.</li>
<li><span class="label warning">Warning</span> Cells with a <code>colspan</code> will attempt to use the parser set for that column and <em>will not</em> use the parser for another column while sorting or filtering - try this <button class="search" data-column="3" type="button">&gt;10</button> - the "17 Koala" cell is not parsed as a numeric value and is thus considered a string.</li>
<li>The <code>duplicateSpan</code> option (storing of cache data) is a preliminary step in providing <code>colspan</code> support, it is by no means complete.</li>
<li>The <a href="index.html#duplicatespan"><code>duplicateSpan</code></a> option (storing of cache data) is a preliminary step in providing <code>colspan</code> support, it is by no means complete.</li>
<li>Ignore an entire <em>header</em> row by adding a "tablesorter-ignoreRow" class (set by the <a href="index.html#cssignorerow"><code>cssIgnoreRow</code></a> option).</li>
<li>This demo requires tablesorter v2.25.0+, as well the corresponding version of the filter widget.<br><br></li>
<li>Follow the demo steps to hopefully get the full understanding of how to use <code>colspan</code>s in the tbody.</li>
@ -129,6 +130,9 @@ Search:
<table class="tablesorter">
<thead>
<tr class="tablesorter-ignoreRow">
<th colspan="6">This entire row is ignored</th>
</tr>
<tr>
<th rowspan="2" colspan="2">Index (colspan 2)</th>
<th colspan="4">Products</th>
@ -139,6 +143,9 @@ Search:
<th>Animals</th>
<th>Url</th>
</tr>
<tr class="tablesorter-ignoreRow">
<th colspan="6">This entire row is ignored too!</th>
</tr>
</thead>
<tfoot>
<tr>

View File

@ -40,7 +40,7 @@
active : '', // applied when column is sorted
hover : '', // custom css required - a defined bootstrap style may not override other classes
// icon class names
icons : '', // add "icon-white" to make them white; this icon class is added to the <i> in the header
icons : '', // add "bootstrap-icon-white" to make them white; this icon class is added to the <i> in the header
iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
@ -131,7 +131,7 @@
$(this)
.toggleClass('btn-danger btn-success')
.find('i')
.toggleClass('icon-ok icon-remove glyphicon-ok glyphicon-remove').end()
.toggleClass('glyphicon-ok glyphicon-remove').end()
.find('span')
.text(t ? 'disabled' : 'enabled');
$('table').trigger('refreshWidgets', [false]);
@ -192,8 +192,8 @@
<li>This demo shows how to get around an issue with the filter widget:
<ul>
<li>The <span class="label label-info">zebra widget button</span> below was added to show that when bootstrap's "table-striped" class is applied, the css defined zebra striping will not apply correctly because table rows are hidden but still accounted for by the css <code>nth-child()</code> selector.</li>
<li>To better understand this issue, disable the zebra widget (using the toggle button). Now <button type="button" class="filter btn btn-sm btn-primary" data-column="5" data-filter=">80"><i class="icon-white icon-filter glyphicon glyphicon-filter"></i> Filter ">80"</button> in the "Calculus" column.</li>
<li>Try other filter searches with the zebra widget disabled, like <button type="button" class="filter btn btn-sm btn-primary" data-column="2" data-filter="male"><i class="icon-white icon-filter glyphicon glyphicon-filter"></i> Filter "male"</button> in the "Sex" column.</li>
<li>To better understand this issue, disable the zebra widget (using the toggle button). Now <button type="button" class="filter btn btn-sm btn-primary" data-column="5" data-filter=">80"><i class="bootstrap-icon-white glyphicon glyphicon-filter"></i> Filter ">80"</button> in the "Calculus" column.</li>
<li>Try other filter searches with the zebra widget disabled, like <button type="button" class="filter btn btn-sm btn-primary" data-column="2" data-filter="male"><i class="bootstrap-icon-white glyphicon glyphicon-filter"></i> Filter "male"</button> in the "Sex" column.</li>
<li>To solve this issue, just enable the zebra widget and the "even" and "odd" row class names <del>will</del> should over-ride the <code>nth-child()</code> styling.<br><span class="label label-warning">NOTE!</span> This doesn't seem to work in the latest Bootstrap version, so you'll have to remove the "table-striped" class completely from the table.</li>
<li>The only down side is that for custom bootstrap themes, you'll need to edit the "theme.bootstrap.css" file for bootstrap.</li>
</ul>
@ -204,9 +204,9 @@
<h1>Demo</h1>
<!-- use the filter_reset : '.reset' option or include data-filter="" using the filter button demo code to reset the filters -->
<div class="bootstrap_buttons">
Reset filter : <button type="button" class="reset btn btn-primary" data-column="0" data-filter=""><i class="icon-white icon-refresh glyphicon glyphicon-refresh"></i> Reset filters</button>
Reset filter : <button type="button" class="reset btn btn-primary" data-column="0" data-filter=""><i class="bootstrap-icon-white glyphicon glyphicon-refresh"></i> Reset filters</button>
<br>
Zebra widget : <button type="button" class="zebra btn btn-success"><i class="icon-white icon-ok glyphicon glyphicon-ok"></i> <span>enabled</span></button>
Zebra widget : <button type="button" class="zebra btn btn-success"><i class="bootstrap-icon-white glyphicon glyphicon-ok"></i> <span>enabled</span></button>
</div>
<br>

View File

@ -125,17 +125,23 @@
<div id="main">
<div class="alert alert-warning" role="alert">
<strong>NOTE!</strong>: Bootstrap v4.x is still in alpha development. Do not use it, or the <code>theme.bootstrap_4.css</code> theme file in production until a stable release is available.
<strong>NOTE!</strong>: Bootstrap v4.x is still in beta development. We do not recommend using it, or the <code>theme.bootstrap_4.css</code> theme file <em>in production</em> until a stable release is available.
</div>
<ul>
<li>Go to <a href="example-option-theme-bootstrap-v3.html">Bootstrap v3.x</a> or <a href="example-option-theme-bootstrap-v2.html">Bootstrap v2.x</a> demo.<br><br></li>
<li>Go to <a href="example-option-theme-bootstrap-v3.html">Bootstrap v3.x</a> or <a href="example-option-theme-bootstrap-v2.html">Bootstrap v2.x</a> demo.</li>
<li>Get the current version of <a href="https://getbootstrap.com/">Bootstrap</a> (now v4.x).<br><br></li>
<li>In <span class="version updated">v2.28.4</span>, added this Bootstrap v4.x demo.</li>
<li>This demo uses <a href="https://v4-alpha.getbootstrap.com/">Bootstrap v4.x</a> (currently v4.0.0-alpha.6).</li>
<li>In <span class="version updated">v2.29.0</span>, updated to use Bootstrap v4.0.0-beta.</li>
<li>In <span class="version">v2.28.4</span>, added this Bootstrap v4.0.0-alpha.6 demo.</li>
<li>Notes:
<ul>
<li>This version of the theme <strong>no longer requires the UITheme widget</strong>!</li>
<li>Bootstrap v4.x no longer includes fonts or images, so I didn't bother including Font Awesome icons on this demo page.</li>
<li>For more information like revision history of this theme &amp; why there is a button to enable/disable the zebra widget, please see the <a href="example-option-theme-bootstrap-v3.html">Bootstrap v3.x demo</a>.</li>
</ul>
</li>
</ul>
<h1>Demo</h1>
<!-- use the filter_reset : '.reset' option or include data-filter="" using the filter button demo code to reset the filters -->

View File

@ -94,7 +94,7 @@ td:nth-child(3) .ts-align-right i {
<li>This widget will <strong>only work</strong> in tablesorter version 2.8+ and jQuery version 1.7+.</li>
<li>Make sure to include the CSS shown below to maintain the alignment.</li>
<li><span class="label warning">*NOTE*</span> if the table cell becomes too narrow, the alignment <strong>will not</strong> be maintained &amp; some content may overflow into the next/previous cell (the widget css does include <code>overflow:hidden</code> on the wrapper, so some content will be hidden instead of overflowing).</li>
<li>Until the day that <code>text-align: '.';</code> becomes standard (<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-align">ref</a>), if ever, this widget might prove useful.</li>
<li>Until the day that <code>text-align: '.' center;</code> becomes standard in CSS4 (<a href="https://www.w3.org/TR/css-text-4/#character-alignment">ref</a>), if ever, this widget might prove useful.</li>
</ul>
</div>

View File

@ -137,7 +137,13 @@
// class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
// applied icons; use this class name (input.checked) instead of input:checked
columnSelector_cssChecked : 'checked'
columnSelector_cssChecked : 'checked',
// class name added to rows that have a span (e.g. grouping widget & other rows inside the tbody)
columnSelector_classHasSpan : 'hasSpan',
// event triggered when columnSelector completes
columnSelector_updated : 'columnUpdate'
}
});
@ -182,6 +188,7 @@
<h3><a href="#">Notes</a></h3>
<div>
<ul>
<li>In <span class="version">v2.29.0</span>, added a <code>columnSelector_classHasSpan</code> setting.</li>
<li>In <span class="version">v2.27.0</span>,
<ul>
<li>Added two new options: <code>columnSelector_maxVisible</code> and <code>columnSelector_minVisible</code>.</li>
@ -526,6 +533,18 @@
</td>
</tr>
<tr id="column-selector-class-has-span">
<td><a href="#" class="permalink">columnSelector_classHasSpan</a></td>
<td>
Class name added to rows that have a span (e.g. grouping widget & other rows inside the tbody) (<span class="version">v2.29.0</span>)
<div class="collapsible">
<p>This was added to allow customizing the css name in case of conflicts.</p>
<p>The grouping widget accesses this value to ensure that group rows are not hidden when the first column is toggled.</p>
Default value: <code>'hasSpan'</code>
</div>
</td>
</tr>
<tr id="column-selector-updated">
<td><a href="#" class="permalink">columnSelector_updated</a></td>
<td>

View File

@ -271,6 +271,7 @@ table.tablesorter tbody tr.even.checked td {
<h4>Changes</h4>
<ul>
<li>In <span class="version">v2.29.0</span>, updated internal function parameters to make it easier to output all table data from the server without modifying the current table, or changing the pager size or page. See the modified <code>output_callback</code> code in the <a class="intlink" href="#setup_example_php">Output all data</a> section.</li>
<li>In <span class="version">v2.28.5</span>, triggering of the "outputTable" event multiple times in rapid succession (within 600 milliseconds) will now prevent the opening of multiple popups or cause mutliple downloads.</li>
<li>In <span class="version">v2.28.4</span>,
<ul>
@ -280,15 +281,15 @@ table.tablesorter tbody tr.even.checked td {
</ul>
</li>
<li>In <span class="version">v2.27.0</span>, the <a class="intlink" href="#output_callback"><code>output_callback</code></a> now includes a <code>url</code> parameter.</li>
<li>In <span class="version">v2.25.2</span>, updated the <a class="intlink" href="#output_saverows"><code>output_saveRows</code></a> option to accept a function.</li>
<li>In <span class="version">v2.25.1</span>, the <a class="intlink" href="#output_callback"><code>output_callback</code></a> can return modified data instead of a boolean.</li>
<li>In <span class="version">v2.22.4</span>, added <a class="intlink" href="#output_formatcontent"><code>output_formatContent</code></a> callback function which allows for extra formatting of cell content (e.g. convert <code>'&amp;amp;'</code> &rarr; <code>'&amp;'</code>).</li>
</ul>
<div class="accordion start-closed">
<h3 id="old-notes"><a href="#">Older Notes</a></h3>
<div>
<ul>
<li>In <span class="version">v2.25.2</span>, updated the <a class="intlink" href="#output_saverows"><code>output_saveRows</code></a> option to accept a function.</li>
<li>In <span class="version">v2.25.1</span>, the <a class="intlink" href="#output_callback"><code>output_callback</code></a> can return modified data instead of a boolean.</li>
<li>In <span class="version">v2.22.4</span>, added <a class="intlink" href="#output_formatcontent"><code>output_formatContent</code></a> callback function which allows for extra formatting of cell content (e.g. convert <code>'&amp;amp;'</code> &rarr; <code>'&amp;'</code>).</li>
<li>In <span class="version">v2.22.2</span>,
<ul>
<li>The data-attribute used by the <code>output_dataAttrib</code> can now be an empty string.</li>
@ -427,12 +428,25 @@ table.tablesorter tbody tr.even.checked td {
</div>
<h3><a href="#">Setup Example (php)</a></h3>
<div>
<div class="accordion start-closed">
<h3><a href="#">Basic Example</a></h3>
<div>
Thanks to <a href="https://github.com/TheSin-">TheSin-</a> for sharing this setup which includes the necessary php to allow file download with the proper filename and extension (<a href="https://gist.github.com/TheSin-/3303c23f033bd973bf34">original Gist</a>)
<p></p>
<script src="https://gist.github.com/TheSin-/3303c23f033bd973bf34.js"></script>
</div>
<h3><a href="#">Output all data</a></h3>
<div>
This code example can be used in <span class="version updated">v2.29.0+</span> to load in all data to output it directly. It will not manipulate the data currently in the table.
<p></p>
<script src="https://gist.github.com/TheSin-/ce24a9b551ae3ebd8f4828bae7ea572d.js"></script>
</div>
</div>
</div>
<h3><a href="#">Rowspan and colspan</a></h3>
<div>
<ul>

View File

@ -111,6 +111,7 @@
<li><span class="label label-info">IMPORTANT</span> The resizable will not work properly if the <a href="index.html#widthfixed"><code>widthFixed</code></a> option is set to <code>true</code>. Make sure it is set to <code>false</code> (default setting).</li>
<li><del><span class="label label-info">IMPORTANT</span> The resize div ends up with a zero height if the header cell is empty. Please include at least a <code>&amp;nbsp;</code> in the cell to allow it to render properly (<a href="https://github.com/Mottie/tablesorter/issues/844" title="Thanks gigib82!">ref</a>)</del>. No longer necessary as the resizable widget no longer adds elements inside the table header cells.<br><br></li>
<li>In <span class="version">v2.29.0</span>, added a <a class="intlink" href="#resizablecomplete"><code>resizableComplete</code></a> event.</li>
<li>In <span class="version">v2.28.8</span>, added the <a class="intlink" href="#resizable-include-footer"><code>resizable_includeFooter</code></a> option.</li>
<li>In <span class="version">v2.28.5</span>,
<ul>
@ -239,7 +240,7 @@ resizable_widths : [ '10%', '10%', '40px', '10%', '100px' ]</pre>
</table>
</div>
<h3><a href="#">Events</a></h3>
<h3><a href="#">Methods</a></h3>
<div>
<h3>resizableUpdate</h3>
<blockquote>
@ -255,6 +256,25 @@ $( 'table' ).trigger( 'resizableUpdate' );</pre>
</blockquote>
</div>
<h3><a href="#">Events</a></h3>
<div>
<h3>resizableComplete</h3>
<blockquote>
A <code>resizableComplete</code> event (added <span class="version">v2.29.0</span>) is triggered on the table after the user has resized a column and
<pre class="prettyprint lang-js">$( 'table' ).on( 'resizableComplete', function(event) {
var resizable_vars = this.config.widgetOptions.resizable_vars;
var saved = {
// resizable_vars.storedSizes is an empty array when no resizing was done
// otherwise it contains each column width (padding &amp; border width not included) in pixels
columnWidths: resizable_vars.storedSizes,
// overall table width
tableWidth: resizable_vars.tableWidth
};
// do something with the values
});</pre>
</blockquote>
</div>
</div>
<h1>Demo</h1>

View File

@ -42,6 +42,9 @@
sort2Hash_directionText : [ 0, 1 ], // default values
// if true, override saveSort widget sort, if used & stored sort is available
sort2Hash_overrideSaveSort : true, // default = false
// if true, hash changes are not saved to browser history
sort2Hash_replaceHistory : false,
sort2Hash_encodeHash : null,
/* how to use encodeHash
sort2Hash_encodeHash : function( config, tableId, component, value, rawValue ) {
@ -209,6 +212,17 @@
<td>if <code>true</code>, the hash sort will override any stored sort (saveSort widget).</td>
</tr>
<tr id="sort2hash_replacehistory">
<td><a href="#" class="permalink">sort2Hash_replaceHistory</a></td>
<td><code>false</code></td>
<td>Change how the browser history is managed (<span class="version">v2.29.0</span>)
<div class="collapsible">
<p>If <code>true</code>, all hash changes are not saved to browser history, so when the user presses the back arrow, they will be returned to the previous page.</p>
If <code>false</code>, all hash changes are preserved in the browser history, so when the user presses the back arrow, the hash will show the previous state, but the table won't update unless the page is refreshed.
</div>
</td>
</tr>
<tr id="sort2hash_encodehash">
<td><a href="#" class="permalink">sort2Hash_encodeHash</a></td>
<td><code>null</code></td>

View File

@ -63,6 +63,7 @@ table.tablesorter tbody tr.alt-row td {
<li>This widget is part of the plugin, but has been modified from the original.</li>
<li>The original "widgetZebra" option has been replaced by "widgetOptions.zebra". See the javascript block below for more details (v2.1).</li>
<li>If the "widgetZebra" option exists, it will over-ride this newer "widgetOptions.zebra" option in order to maintain backwards compatibility.</li>
<li>The zebra widget only applies to visible rows, so if the table isn't visible in the beginning, you must use <code>$('table').trigger('applyWidgets');</code> when the table becomes visible (See <a href='https://github.com/Mottie/tablesorter/issues/224#issuecomment-13086515'>issue #224</a>)</li>
</ul>
<h1>Demo</h1>

View File

@ -461,7 +461,7 @@
<li><span class="label label-info">Beta</span> <a href="example-widget-chart.html">Chart Widget</a> (<span class="version">v2.19.0</span>; <span class="version updated">v2.24.0</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-columns.html">Columns highlight widget</a> (v2.0.17; <span class="version updated">v2.28.11</span>).</li>
<li><a href="example-widget-column-selector.html">Column selector widget</a> (<span class="version">v2.15</span>; <span class="version updated">v2.28.15</span>).</li>
<li><a href="example-widget-column-selector.html">Column selector widget</a> (<span class="version">v2.15</span>; <span class="version updated">v2.29.0</span>).</li>
<li><a href="example-widget-editable.html">Content editable widget</a> (v2.9; <span class="version updated">v2.28.7</span>).</li>
<li><a href="example-widget-current-sort.html">Current Sort Widget</a> (<span class="version">v2.27.0</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-dragtable.html">Dragtable mod</a> - (jQuery UI widget for column reordering [<a class="external" href="http://stackoverflow.com/a/27770224/145346">ref</a>]; <span class="version">v2.24.0</span>).</li>
@ -483,7 +483,7 @@
<li><span class="label label-info">Beta</span> <a href="example-widget-formatter.html">Formatter widget</a> (<span class="version">v2.19.1</span>).</li>
<li>Grouping rows widget:
<ul>
<li><a href="example-widget-grouping.html">basic</a> (v2.8; <span class="version updated">v2.27.6</span>).</li>
<li><a href="example-widget-grouping.html">basic</a> (v2.8; <span class="version updated">v2.29.0</span>).</li>
<li><a href="example-widget-grouping-filter-childrows.html">Grouping + filter + child rows</a> (<span class="updated version">v2.28.0</span>).</li>
</ul>
</li>
@ -492,7 +492,7 @@
<li><a href="example-widget-mark.html">Mark widget</a> (<span class="version">v2.27.6</span>).</li>
<li><a href="example-widget-math.html">Math widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.28.0</span>).</li>
<li>
<a href="example-widget-output.html">Output widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.28.6</span>).
<a href="example-widget-output.html">Output widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.29.0</span>).
<br><br>
</li>
@ -505,26 +505,26 @@
<li><a href="example-widget-print.html">Print widget</a> (<span class="version">v2.16.4</span>; <span class="version updated">v2.25.8</span>).</li>
<li><a href="example-widget-reflow.html">Reflow widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.19.0</span>).</li>
<li><a href="example-widgets.html">Repeat headers widget</a> (v2.0.5; <span class="version updated">v2.19.0</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-resizable.html">Resizable columns widget</a> (v2.0.23.1; <span class="version updated">v2.28.8</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-resizable.html">Resizable columns widget</a> (v2.0.23.1; <span class="version updated">v2.29.0</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-savesort.html">Save sort widget</a> (v2.0.27; <span class="version updated">v2.24.0</span>).</li>
<li><a href="example-widget-scroller.html">Scroller widget</a> (<span class="version">v2.9</span>; <span class="version updated">v2.28.8</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-sort-to-hash.html">Sort-to-hash widget</a> (<span class="version">v2.22.4</span>; <span class="version updated">v2.28.15</span>).</li>
<li><a href="example-widget-scroller.html">Scroller widget</a> (<span class="version">v2.9</span>; <span class="version updated">v2.29.0</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-sort-to-hash.html">Sort-to-hash widget</a> (<span class="version">v2.22.4</span>; <span class="version updated">v2.29.0</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-sort-tbodies.html">Sort tbodies widget</a> (<span class="version">v2.22.2</span>; <span class="version updated">v2.28.0</span>).</li>
<li><a href="example-widget-static-row.html">Static row widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.24.0</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-sticky-header.html">Sticky header widget</a> (v2.0.21.1; <span class="version updated">v2.28.13</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-sticky-header.html">Sticky header widget</a> (v2.0.21.1; <span class="version updated">v2.29.0</span>).</li>
<li><a href="example-widget-css-sticky-header.html">Sticky header (css3) widget</a> (<span class="version">v2.14.2</span>; <span class="version updated">v2.28.11</span>).</li>
<li><span class="results">&dagger;</span> <a href="#function-storage">Storage Widget</a> (<span class="version">v2.20.0</span>; <span class="version updated">v2.28.8</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-toggle-tablesorter.html">Toggle Sort & Filter Widget</a> (<span class="version">v2.24.4</span>).</li>
<li><span class="results">&dagger;</span> UITheme widget (<span class="version">v2.0.9</span>; <span class="version updated">v2.27.0</span>):
<li><span class="results">&dagger;</span> UITheme widget (<span class="version">v2.0.9</span>; <span class="version updated">v2.29.0</span>):
<ul>
<li><a href="example-widget-ui-theme.html">jQuery UI theme</a> (v2.0.9; <span class="version updated">v2.27.0</span>).</li>
<li><a href="example-option-theme-bootstrap-v2.html">Bootstrap v2.x</a> (demo added <span class="version">v2.22.0</span>).</li>
<li><a href="example-option-theme-bootstrap-v3.html">Bootstrap v3.x</a> (v2.4.0; <span class="version updated">v2.28.4</span>).</li>
<li><a href="example-option-theme-bootstrap-v4.html">Bootstrap v4.x</a> (<span class="version updated">v2.28.4</span>) <span class="label warning">NOTE</span> <strong>does not</strong> require the uitheme widget!</li>
<li><a href="example-option-theme-bootstrap-v4.html">Bootstrap v4.x</a> (<span class="version updated">v2.29.0</span>) <span class="label warning">NOTE</span> <strong>does not</strong> require the uitheme widget!</li>
</ul>
</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-view.html">View Widget</a> (<span class="version">v2.24.0</span>; <span class="version updated">v2.26.6</span>).</li>
@ -617,7 +617,7 @@
</ul>
</div>
</td>
<td><a href="example-widget-filter.html">Example</a></td>
<td><a href="example-colspan.html">Example</a></td>
</tr>
<tr id="cssasc">
@ -880,7 +880,7 @@
This class name should be added to header rows that contain custom HTML, like for the pager controls, custom filter row or table toolbar.
</div>
</td>
<td><a href="example-pager-ajax.html#html">Example</a></td>
<td><a href="example-colspan.html">1</a> <a href="example-pager-ajax.html#html">2</a></td>
</tr>
<tr id="dateformat">
@ -2646,13 +2646,13 @@ $(function(){
When the filter row is built, each table cell (<code>&lt;td&gt;</code>) will get the class name from this option.
<ul>
<li>If this option is a plain string, all filter row cells will get the text applied as a class name.
<pre class="prettyprint lang-js">// "table-filter" class added to all filter row td's
filter_cssFilter : 'table-filter'</pre>
<pre class="prettyprint lang-js">// "table-filter-cell" class added to all filter row td's
filter_cellFilter : 'table-filter-cell'</pre>
</li>
<li>If this option is an array, then each filter row cell will get the text from the associate array element applied as a class name.
<pre class="prettyprint lang-css">.hidden { display: none; }</pre>
<pre class="prettyprint lang-js">// hiding second & fourth columns using associated css
filter_cssFilter : [ '', 'hidden', '', 'hidden' ]</pre>
filter_cellFilter : [ '', 'hidden', '', 'hidden' ]</pre>
</li>
</ul>
<p>Use the <a href="#widget-filter-cellfilter"><code>filter_cellFilter</code></a> option to add an extra css class name as follows:</p>
@ -5530,16 +5530,19 @@ $.tablesorter.updateCell( config, $cell, resort, callback );</pre>
<tr id="applywidgets">
<td><a href="#" class="permalink">applyWidgets</a></td>
<td>Apply the set widgets to the table (<span class="version updated">v2.16.0</span>).
<td>Apply the set widgets to the table (<span class="version updated">v2.29.0</span>).
<div class="collapsible">
<p>In <span class="version updated">v2.29.0</span>, access to the callback method was added.</p>
<p>This method only updates the widgets listed in the <a href="#widgets"><code>table.config.widgets</code></a> option.</p>
<pre class="prettyprint lang-js">// This method applies the widgets already added to tablesorter
$('table').trigger('applyWidgets');
$('table').trigger('applyWidgets', callback);
</pre>
Use this method can be used to add multiple widgets to the table.
<pre class="prettyprint lang-js">var $table = $( 'table' );
$table[0].config.widgets = [ 'zebra', 'columns' ];
$table.trigger('applyWidgets');
$table.trigger('applyWidgets', function() {
console.log('new widgets applied');
});
</pre></div>
</td>
<td><a href="example-apply-widget.html">Example</a></td>
@ -6068,6 +6071,21 @@ $.tablesorter.storage( $('#myTable'), 'tablesorter-filters', '' );</pre>
<td></td>
</tr>
<tr id="widgetremoveend">
<td><a href="#" class="permalink">widgetRemoveEnd</a></td>
<td>Event triggered after <em>any</em> widget has finished being removed (<span class="version">v2.29.0</span>).
<div class="collapsible"><br>
You can use this event to do something like remove the class added to the filter row when the filtering started. Use it as follows:<pre class="prettyprint lang-js">$(function(){
$('table').bind('widgetRemoveEnd', function(event, table) {
// do something after widget was removed
});
});</pre>
This method does not include data on which widget was removed.
</div>
</td>
<td><a href="example-option-show-processing.html">Example</a></td>
</tr>
</tbody>
<!-- non-sorting tbody -->

View File

@ -4,7 +4,7 @@
*/
/*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/* 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.28.15 *//*
/*! TableSorter (FORK) v2.29.0 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -40,7 +40,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.28.15',
version : '2.29.0',
parsers : [],
widgets : [],
@ -439,10 +439,10 @@
e.stopPropagation();
ts.applyWidgetId( this, id );
})
.bind( 'applyWidgets' + namespace, function( e, init ) {
.bind( 'applyWidgets' + namespace, function( e, callback ) {
e.stopPropagation();
// apply widgets
ts.applyWidget( this, init );
// apply widgets (false = not initializing)
ts.applyWidget( this, false, callback );
})
.bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
e.stopPropagation();
@ -479,9 +479,9 @@
downTarget = null;
if ( core !== true ) {
$headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
$( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
tmp = ts.getClosest( $headers, 'table' );
if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
$( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
}
}
tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@ -533,8 +533,7 @@
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
/TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
$cell = ts.getHeaderCell( $( this ) );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -574,7 +573,7 @@
'';
// 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,
var configHeaders, header, column, template, tmp, $th,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@ -600,7 +599,9 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
column = parseInt( $elem.attr( 'data-column' ), 10 );
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.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
@ -618,10 +619,9 @@
}
// add cell to headerList
c.headerList[ index ] = elem;
$elem.addClass( ts.css.header + ' ' + c.cssHeader );
// add to parent in case there are multiple rows
$elem
.addClass( ts.css.header + ' ' + c.cssHeader )
.parent()
ts.getClosest( $elem, 'tr' )
.addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
.attr( 'role', 'row' );
// allow keyboard cursor to focus on element
@ -1179,10 +1179,29 @@
}
},
// 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 /TH|TD/.test( $el[0].nodeName ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var column = parseInt( $header.attr( 'data-column' ), 10 ),
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1340,10 +1359,9 @@
$cell = $( cell ),
// update cache - format: function( s, table, cell, cellIndex )
// no closest in jQuery v1.2.6
tbodyIndex = $tbodies
.index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
tbcache = c.cache[ tbodyIndex ],
$row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
$row = ts.getClosest( $cell, 'tr' );
cell = $cell[ 0 ]; // in case cell is a jQuery object
// tbody may not exist if update is initialized while tbody is removed for processing
if ( $tbodies.length && tbodyIndex >= 0 ) {
@ -1398,11 +1416,13 @@
if ( valid ) {
$row = $( $row );
c.$tbodies.append( $row );
} else if ( !$row ||
} else if (
!$row ||
// row is a jQuery object?
!( $row instanceof jQuery ) ||
// row contained in the table?
( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
) {
if ( c.debug ) {
console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@ -1549,10 +1569,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index
col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -2076,7 +2096,7 @@
if ( !widget.priority ) { widget.priority = 10; }
widgets[ indx ] = widget;
} else if ( c.debug ) {
console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
}
}
// sort widgets by priority
@ -2148,6 +2168,7 @@
c.widgetInit[ name[ index ] ] = false;
}
}
c.$table.triggerHandler( 'widgetRemoveEnd', table );
},
refreshWidgets : function( table, doAll, dontapply ) {
@ -2999,7 +3020,7 @@
})(jQuery, window, document);
/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
@ -3016,10 +3037,10 @@
active : '', // applied when column is sorted
hover : '', // custom css required - a defined bootstrap style may not override other classes
// icon class names
icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
filterRow : '', // filter row class
footerRow : '',
footerCells : '',
@ -5202,7 +5223,7 @@
})( jQuery );
/*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.4.3+
* by Rob Garrison
*/
@ -5354,10 +5375,14 @@
});
}
},
getLeftPosition = function() {
return $attach.length ?
parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
},
resizeHeader = function() {
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
left : getLeftPosition(),
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
@ -5367,10 +5392,10 @@
if (!$table.is(':visible')) { return; } // fixes #278
// Detect nested tables - fixes #724
nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
var offset = $table.offset(),
var tmp,
offset = $table.offset(),
stickyOffset = getStickyOffset(c, wo),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
attachTop = $attach.length ?
( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
$yScroll.scrollTop(),
@ -5378,19 +5403,27 @@
scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
needsUpdating = !$stickyWrap.hasClass( state ),
cssSettings = { visibility : isVisible };
if ($attach.length) {
// attached sticky headers always need updating
needsUpdating = true;
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
}
if (xWindow) {
// adjust when scrolling horizontally - fixes issue #143
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
tmp = getLeftPosition();
if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
needsUpdating = true;
cssSettings.left = tmp;
}
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
if (needsUpdating) {
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.addClass( state )
.css(cssSettings);
}
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();
@ -5509,7 +5542,7 @@
})(jQuery, window);
/*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
/*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
/*jshint browser:true, jquery:true, unused:false */
;(function ($, window) {
'use strict';
@ -5836,6 +5869,7 @@
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.triggerHandler('stickyHeadersUpdate');
c.$table.triggerHandler('resizableComplete');
}
};

View File

@ -1,4 +1,4 @@
/*! TableSorter (FORK) v2.28.15 *//*
/*! TableSorter (FORK) v2.29.0 *//*
* Client-side table sorting with ease!
* @requires jQuery v1.2.6+
*
@ -22,7 +22,7 @@
'use strict';
var ts = $.tablesorter = {
version : '2.28.15',
version : '2.29.0',
parsers : [],
widgets : [],
@ -421,10 +421,10 @@
e.stopPropagation();
ts.applyWidgetId( this, id );
})
.bind( 'applyWidgets' + namespace, function( e, init ) {
.bind( 'applyWidgets' + namespace, function( e, callback ) {
e.stopPropagation();
// apply widgets
ts.applyWidget( this, init );
// apply widgets (false = not initializing)
ts.applyWidget( this, false, callback );
})
.bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) {
e.stopPropagation();
@ -461,9 +461,9 @@
downTarget = null;
if ( core !== true ) {
$headers.addClass( namespace.slice( 1 ) + '_extra_headers' );
tmp = $.fn.closest ? $headers.closest( 'table' )[ 0 ] : $headers.parents( 'table' )[ 0 ];
if ( tmp && tmp.nodeName === 'TABLE' && tmp !== table ) {
$( tmp ).addClass( namespace.slice( 1 ) + '_extra_table' );
tmp = ts.getClosest( $headers, 'table' );
if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) {
$( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' );
}
}
tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' )
@ -515,8 +515,7 @@
ts.buildCache( c );
}
// jQuery v1.2.6 doesn't have closest()
$cell = $.fn.closest ? $( this ).closest( 'th, td' ) :
/TH|TD/.test( this.nodeName ) ? $( this ) : $( this ).parents( 'th, td' );
$cell = ts.getHeaderCell( $( this ) );
// reference original table headers and find the same cell
// don't use $headers or IE8 throws an error - see #987
temp = $headers.index( $cell );
@ -556,7 +555,7 @@
'';
// 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,
var configHeaders, header, column, template, tmp, $th,
$elem = $( elem );
// ignore cell (don't add it to c.$headers) if row has ignoreRow class
if ( $elem.parent().hasClass( c.cssIgnoreRow ) ) { return; }
@ -582,7 +581,9 @@
if ( c.onRenderHeader ) {
c.onRenderHeader.apply( $elem, [ index, c, c.$table ] );
}
column = parseInt( $elem.attr( 'data-column' ), 10 );
// data-column stored on th or td only
$th = ts.getHeaderCell( $elem );
column = parseInt( $th.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
@ -600,10 +601,9 @@
}
// add cell to headerList
c.headerList[ index ] = elem;
$elem.addClass( ts.css.header + ' ' + c.cssHeader );
// add to parent in case there are multiple rows
$elem
.addClass( ts.css.header + ' ' + c.cssHeader )
.parent()
ts.getClosest( $elem, 'tr' )
.addClass( ts.css.headerRow + ' ' + c.cssHeaderRow )
.attr( 'role', 'row' );
// allow keyboard cursor to focus on element
@ -1161,10 +1161,29 @@
}
},
// 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 /TH|TD/.test( $el[0].nodeName ) ?
$el :
$el.parents( 'th, td' ).filter( ':first' );
},
// nextSort (optional), lets you disable next sort text
setColumnAriaLabel : function( c, $header, nextSort ) {
if ( $header.length ) {
var column = parseInt( $header.attr( 'data-column' ), 10 ),
var $th = ts.getHeaderCell( $header ),
// data-column always stored on the th/td
column = parseInt( $th.attr( 'data-column' ), 10 ),
vars = c.sortVars[ column ],
tmp = $header.hasClass( ts.css.sortAsc ) ?
'sortAsc' :
@ -1322,10 +1341,9 @@
$cell = $( cell ),
// update cache - format: function( s, table, cell, cellIndex )
// no closest in jQuery v1.2.6
tbodyIndex = $tbodies
.index( $.fn.closest ? $cell.closest( 'tbody' ) : $cell.parents( 'tbody' ).filter( ':first' ) ),
tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ),
tbcache = c.cache[ tbodyIndex ],
$row = $.fn.closest ? $cell.closest( 'tr' ) : $cell.parents( 'tr' ).filter( ':first' );
$row = ts.getClosest( $cell, 'tr' );
cell = $cell[ 0 ]; // in case cell is a jQuery object
// tbody may not exist if update is initialized while tbody is removed for processing
if ( $tbodies.length && tbodyIndex >= 0 ) {
@ -1380,11 +1398,13 @@
if ( valid ) {
$row = $( $row );
c.$tbodies.append( $row );
} else if ( !$row ||
} else if (
!$row ||
// row is a jQuery object?
!( $row instanceof jQuery ) ||
// row contained in the table?
( $.fn.closest ? $row.closest( 'table' )[ 0 ] : $row.parents( 'table' )[ 0 ] ) !== c.table ) {
( ts.getClosest( $row, 'table' )[ 0 ] !== c.table )
) {
if ( c.debug ) {
console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' +
'been added to the table, or (2) row HTML string to be added to a table with only one tbody' );
@ -1531,10 +1551,10 @@
notMultiSort = !event[ c.sortMultiSortKey ],
table = c.table,
len = c.$headers.length,
// get current column index
col = parseInt( $( cell ).attr( 'data-column' ), 10 ),
// get current column index; *always* stored on th/td
$th = ts.getHeaderCell( $( cell ) ),
col = parseInt( $th.attr( 'data-column' ), 10 ),
order = c.sortVars[ col ].order;
// Only call sortStart if sorting is enabled
c.$table.triggerHandler( 'sortStart', table );
// get current column sort order
@ -2058,7 +2078,7 @@
if ( !widget.priority ) { widget.priority = 10; }
widgets[ indx ] = widget;
} else if ( c.debug ) {
console.warn( '"' + names[ indx ] + '" widget code does not exist!' );
console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' );
}
}
// sort widgets by priority
@ -2130,6 +2150,7 @@
c.widgetInit[ name[ index ] ] = false;
}
}
c.$table.triggerHandler( 'widgetRemoveEnd', table );
},
refreshWidgets : function( table, doAll, dontapply ) {

View File

@ -4,7 +4,7 @@
*/
/*! tablesorter (FORK) - updated 07-04-2017 (v2.28.15)*/
/*! tablesorter (FORK) - updated 09-27-2017 (v2.29.0)*/
/* Includes widgets ( storage,uitheme,columns,filter,stickyHeaders,resizable,saveSort ) */
(function(factory) {
if (typeof define === 'function' && define.amd) {
@ -133,7 +133,7 @@
})(jQuery, window, document);
/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
@ -150,10 +150,10 @@
active : '', // applied when column is sorted
hover : '', // custom css required - a defined bootstrap style may not override other classes
// icon class names
icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
filterRow : '', // filter row class
footerRow : '',
footerCells : '',
@ -2336,7 +2336,7 @@
})( jQuery );
/*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.4.3+
* by Rob Garrison
*/
@ -2488,10 +2488,14 @@
});
}
},
getLeftPosition = function() {
return $attach.length ?
parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
},
resizeHeader = function() {
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
left : getLeftPosition(),
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
@ -2501,10 +2505,10 @@
if (!$table.is(':visible')) { return; } // fixes #278
// Detect nested tables - fixes #724
nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
var offset = $table.offset(),
var tmp,
offset = $table.offset(),
stickyOffset = getStickyOffset(c, wo),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
attachTop = $attach.length ?
( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
$yScroll.scrollTop(),
@ -2512,19 +2516,27 @@
scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
needsUpdating = !$stickyWrap.hasClass( state ),
cssSettings = { visibility : isVisible };
if ($attach.length) {
// attached sticky headers always need updating
needsUpdating = true;
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
}
if (xWindow) {
// adjust when scrolling horizontally - fixes issue #143
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
tmp = getLeftPosition();
if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
needsUpdating = true;
cssSettings.left = tmp;
}
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
if (needsUpdating) {
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.addClass( state )
.css(cssSettings);
}
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();
@ -2643,7 +2655,7 @@
})(jQuery, window);
/*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
/*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
/*jshint browser:true, jquery:true, unused:false */
;(function ($, window) {
'use strict';
@ -2970,6 +2982,7 @@
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.triggerHandler('stickyHeadersUpdate');
c.$table.triggerHandler('resizableComplete');
}
};

View File

@ -1,4 +1,4 @@
/* Widget: columnSelector (responsive table widget) - updated 7/4/2017 (v2.28.15) *//*
/* Widget: columnSelector (responsive table widget) - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Justin Hallett & Rob Garrison
*/
@ -269,16 +269,16 @@
c.$table.triggerHandler(wo.columnSelector_updated);
}
},
addSelectors: function( prefix, column ) {
addSelectors: function( wo, prefix, column ) {
var array = [],
temp = ' col:nth-child(' + column + ')';
array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr:not(.hasSpan) th[data-column="' + ( column - 1 ) + '"]';
temp = ' tr:not(.' + wo.columnSelector_classHasSpan + ') th[data-column="' + ( column - 1 ) + '"]';
array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr:not(.hasSpan) td:nth-child(' + column + ')';
temp = ' tr:not(.' + wo.columnSelector_classHasSpan + ') td:nth-child(' + column + ')';
array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
// for other cells in colspan columns
temp = ' tr td:not(' + prefix + 'HasSpan)[data-column="' + (column - 1) + '"]';
temp = ' tr td:not(' + prefix + wo.columnSelector_classHasSpan + ')[data-column="' + (column - 1) + '"]';
array.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
return array;
},
@ -301,7 +301,7 @@
isHidden[ column + 1 ] = ts.getData( c.$headerIndexed[ column ], col, 'columnSelector' ) === 'false';
if ( isHidden[ column + 1 ] ) {
// hide columnSelector false column (in auto mode)
mediaAll = mediaAll.concat( tsColSel.addSelectors( prefix, column + 1 ) );
mediaAll = mediaAll.concat( tsColSel.addSelectors( wo, prefix, column + 1 ) );
}
}
}
@ -313,7 +313,7 @@
column = parseInt($(this).attr('data-column'), 10) + 1;
// don't reveal columnSelector false columns
if ( !isHidden[ column ] ) {
breaks = breaks.concat( tsColSel.addSelectors( prefix, column ) );
breaks = breaks.concat( tsColSel.addSelectors( wo, prefix, column ) );
}
});
if (breaks.length) {
@ -343,7 +343,7 @@
colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
if (!this.checked) {
column = parseInt( $(this).attr('data-column'), 10 ) + 1;
styles = styles.concat( tsColSel.addSelectors( prefix, column ) );
styles = styles.concat( tsColSel.addSelectors( wo, prefix, column ) );
}
$(this).toggleClass( wo.columnSelector_cssChecked, this.checked );
});
@ -373,10 +373,10 @@
if ( span > 1 ) {
hasSpans = true;
$cells.eq( index )
.addClass( c.namespace.slice( 1 ) + 'columnselectorHasSpan' )
.addClass( c.namespace.slice( 1 ) + 'columnselector' + wo.columnSelector_classHasSpan )
.attr( 'data-col-span', span );
// add data-column values
ts.computeColumnIndex( $cells.eq( index ).parent().addClass( 'hasSpan' ) );
ts.computeColumnIndex( $cells.eq( index ).parent().addClass( wo.columnSelector_classHasSpan ) );
}
}
// only add resize end if using media queries
@ -402,7 +402,9 @@
autoModeOn = wo.columnSelector_mediaquery && colSel.auto,
// find all header/footer cells in case a regular column follows a colspan; see #1238
$headers = c.$table.children( 'thead, tfoot' ).children().children()
.add( $(c.namespace + '_extra_table').children( 'thead, tfoot' ).children().children() ),
.add( $(c.namespace + '_extra_table').children( 'thead, tfoot' ).children().children() )
// include grouping widget headers (they have colspans!)
.add( c.$table.find( '.group-header' ).children() ),
len = $headers.length;
for ( index = 0; index < len; index++ ) {
$cell = $headers.eq(index);
@ -422,7 +424,7 @@
$cell.addClass( filtered );
}
} else if ( typeof colSel.states[ col ] !== 'undefined' && colSel.states[ col ] !== null ) {
$cell.toggleClass( filtered, !colSel.states[ col ] );
$cell.toggleClass( filtered, !autoModeOn && !colSel.states[ col ] );
}
}
},
@ -533,6 +535,8 @@
// class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
// applied icons; use this class name (input.checked) instead of input:checked
columnSelector_cssChecked : 'checked',
// class name added to rows that have a span (e.g. grouping widget & other rows inside the tbody)
columnSelector_classHasSpan : 'hasSpan',
// event triggered when columnSelector completes
columnSelector_updated : 'columnUpdate'
},
@ -546,10 +550,10 @@
if ( csel.$popup ) { csel.$popup.empty(); }
csel.$style.remove();
csel.$breakpoints.remove();
$( c.namespace + 'columnselectorHasSpan' ).removeClass( wo.filter_filteredRow || 'filtered' );
$( c.namespace + 'columnselector' + wo.columnSelector_classHasSpan )
.removeClass( wo.filter_filteredRow || 'filtered' );
c.$table.find('[data-col-span]').each(function(indx, el) {
var $el = $(el);
console.log($el, $el.attr('data-col-span'));
$el.attr('colspan', $el.attr('data-col-span'));
});
c.$table.off('updateAll' + namespace + ' update' + namespace);

View File

@ -1,4 +1,4 @@
/*! Widget: grouping - updated 11/26/2016 (v2.28.0) *//*
/*! Widget: grouping - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
@ -172,7 +172,10 @@
groupHeaderHTML : function( c, wo, data ) {
var name = ( data.currentGroup || '' ).toString().replace(/</g, '&lt;').replace(/>/g, '&gt;');
return '<tr class="group-header ' + c.selectorRemove.slice(1) +
return '<tr class="group-header ' + c.selectorRemove.slice(1) + ' ' +
// prevent grouping row from being hidden by the columnSelector;
// classHasSpan option added 2.29.0
( wo.columnSelector_classHasSpan || 'hasSpan' ) +
'" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
data.groupIndex + '">' +
'<td colspan="' + c.columns + '">' +
@ -221,6 +224,10 @@
}
}
}
if ( ts.hasWidget( c.table, 'columnSelector' ) ) {
// make sure to handle the colspan adjustments of the grouping rows
ts.columnSelector.setUpColspan( c, wo );
}
},
insertGroupHeader: function( c, wo, data ) {
var $header = c.$headerIndexed[ data.column ],

View File

@ -1,4 +1,4 @@
/*! Widget: output - updated 4/2/2017 (v2.28.6) *//*
/*! Widget: output - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.7+
* Modified from:
* HTML Table to CSV: http://www.kunalbabre.com/projects/table2CSV.php (License unknown?)
@ -131,8 +131,10 @@
return data;
},
process : function(c, wo) {
var mydata, $this, $rows, headers, csvData, len, rowsLen, tmp,
// optional vars $rows and dump added by TheSin to make
// process callable via callback for ajaxPager
process : function(c, wo, $rows, dump) {
var mydata, $this, headers, csvData, len, rowsLen, tmp,
hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
indx = 0,
tmpData = (wo.output_separator || ',').toLowerCase(),
@ -162,6 +164,7 @@
headers = output.processRow(c, $this, true, outputJSON);
// all tbody rows - do not include widget added rows (e.g. grouping widget headers)
if ( !$rows )
$rows = $el.children('tbody').children('tr').not(c.selectorRemove);
// check for a filter callback function first! because
@ -210,10 +213,15 @@
mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
}
if (dump) {
return mydata;
}
// callback; if true returned, continue processing
if ($.isFunction(wo.output_callback)) {
tmp = wo.output_callback(c, mydata, c.pager && c.pager.ajaxObject.url || null);
if ( tmp === false ) {
output.busy = false;
return;
} else if ( typeof tmp === 'string' ) {
mydata = tmp;

View File

@ -1,4 +1,4 @@
/*! Widget: resizable - updated 4/18/2017 (v2.28.8) */
/*! Widget: resizable - updated 9/27/2017 (v2.29.0) */
/*jshint browser:true, jquery:true, unused:false */
;(function ($, window) {
'use strict';
@ -325,6 +325,7 @@
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.triggerHandler('stickyHeadersUpdate');
c.$table.triggerHandler('resizableComplete');
}
};

View File

@ -1,4 +1,4 @@
/*! Widget: scroller - updated 4/18/2017 (v2.28.8) *//*
/*! Widget: scroller - updated 9/27/2017 (v2.29.0) *//*
Copyright (C) 2011 T. Connell & Associates, Inc.
Dual-licensed under the MIT and GPL licenses
@ -273,6 +273,9 @@
$tableWrap
.off( 'scroll' + namespace )
.on( 'scroll' + namespace, function() {
// Save position
wo.scroller_saved[0] = $tableWrap.scrollLeft();
wo.scroller_saved[1] = $tableWrap.scrollTop();
if ( wo.scroller_jumpToHeader ) {
var pos = $win.scrollTop() - $hdr.offset().top;
if ( $( this ).scrollTop() !== 0 && pos < tbHt && pos > 0 ) {
@ -841,6 +844,7 @@
// adjust caption height, see #1202
$fixedColumn.find('caption').height( wo.scroller_$header.find( 'caption' ).height() );
$tableWrap.scroll();
wo.scroller_isBusy = false;
},

View File

@ -1,4 +1,4 @@
/*! Widget: sort2Hash (BETA) - updated 7/4/2017 (v2.28.15) */
/*! Widget: sort2Hash (BETA) - updated 9/27/2017 (v2.29.0) */
/* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
@ -225,8 +225,27 @@
hash = s2h.cleanHash( c, wo, component, hash );
str += value;
});
// add updated hash
window.location.hash = ( ( window.location.hash || '' ).replace( '#', '' ).length ? hash : wo.sort2Hash_hash ) + str;
var hashChar = wo.sort2Hash_hash;
// Combine new hash with any existing hashes
var newHash = (
( window.location.hash || '' ).replace( hashChar, '' ).length ?
hash : hashChar
) + str;
if (wo.sort2Hash_replaceHistory) {
var baseUrl = window.location.href.split(hashChar)[0];
// Ensure that there is a leading hash character
var firstChar = newHash[0];
if (firstChar != hashChar) {
newHash = hashChar + newHash;
}
// Update URL in browser
window.location.replace(baseUrl + newHash);
} else {
// Add updated hash
window.location.hash = newHash;
}
}
};
@ -239,6 +258,7 @@
sort2Hash_headerTextAttr : 'data-header', // data attribute containing alternate header text
sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
sort2Hash_overrideSaveSort : false, // if true, override saveSort widget if saved sort available
sort2Hash_replaceHistory : false, // if true, hash changes are not saved to browser history
// this option > table ID > table index on page
sort2Hash_tableId : null,

View File

@ -1,4 +1,4 @@
/*! Widget: stickyHeaders - updated 6/2/2017 (v2.28.13) *//*
/*! Widget: stickyHeaders - updated 9/27/2017 (v2.29.0) *//*
* Requires tablesorter v2.8+ and jQuery 1.4.3+
* by Rob Garrison
*/
@ -150,10 +150,14 @@
});
}
},
getLeftPosition = function() {
return $attach.length ?
parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $(window).scrollLeft();
},
resizeHeader = function() {
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft(),
left : getLeftPosition(),
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
@ -163,10 +167,10 @@
if (!$table.is(':visible')) { return; } // fixes #278
// Detect nested tables - fixes #724
nestedStickyTop = $nestedSticky.length ? $nestedSticky.offset().top - $yScroll.scrollTop() + $nestedSticky.height() : 0;
var offset = $table.offset(),
var tmp,
offset = $table.offset(),
stickyOffset = getStickyOffset(c, wo),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
attachTop = $attach.length ?
( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) :
$yScroll.scrollTop(),
@ -174,19 +178,27 @@
scrollTop = attachTop + stickyOffset + nestedStickyTop - captionHeight,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)) - captionHeight,
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
state = isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide,
needsUpdating = !$stickyWrap.hasClass( state ),
cssSettings = { visibility : isVisible };
if ($attach.length) {
// attached sticky headers always need updating
needsUpdating = true;
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
}
if (xWindow) {
// adjust when scrolling horizontally - fixes issue #143
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft();
tmp = getLeftPosition();
if (tmp !== parseInt($stickyWrap.css('left'), 10)) {
needsUpdating = true;
cssSettings.left = tmp;
}
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
if (needsUpdating) {
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.addClass( state )
.css(cssSettings);
}
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();

View File

@ -1,4 +1,4 @@
/*! Widget: uitheme - updated 12/8/2016 (v2.28.1) */
/*! Widget: uitheme - updated 9/27/2017 (v2.29.0) */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
@ -15,10 +15,10 @@
active : '', // applied when column is sorted
hover : '', // custom css required - a defined bootstrap style may not override other classes
// icon class names
icons : '', // add 'icon-white' to make them white; this icon class is added to the <i> in the header
icons : '', // add 'bootstrap-icon-white' to make them white; this icon class is added to the <i> in the header
iconSortNone : 'bootstrap-icon-unsorted', // class name added to icon when column is not sorted
iconSortAsc : 'icon-chevron-up glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'icon-chevron-down glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
iconSortAsc : 'glyphicon glyphicon-chevron-up', // class name added to icon when column has ascending sort
iconSortDesc : 'glyphicon glyphicon-chevron-down', // class name added to icon when column has descending sort
filterRow : '', // filter row class
footerRow : '',
footerCells : '',

View File

@ -1,7 +1,7 @@
{
"name": "tablesorter",
"title": "tablesorter",
"version": "2.28.15",
"version": "2.29.0",
"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",
@ -58,7 +58,7 @@
"grunt-contrib-clean": "^1.1.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-cssmin": "^2.2.0",
"grunt-contrib-cssmin": "^2.2.1",
"grunt-contrib-jshint": "^1.1.0",
"grunt-contrib-qunit": "^2.0.0",
"grunt-contrib-uglify": "^3.0.1",

View File

@ -1,7 +1,7 @@
{
"name": "tablesorter",
"title": "tablesorter",
"version": "2.28.15",
"version": "2.29.0",
"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",

View File

@ -3,10 +3,10 @@
<head>
<meta charset="utf-8">
<title>Tablesorter Testing (WIP)</title>
<link rel="stylesheet" href="testing/qunit-2.3.1.css">
<link rel="stylesheet" href="testing/qunit-2.4.0.css">
<link rel="stylesheet" href="testing/testing.css">
<script src="testing/qunit-2.3.1.js"></script>
<script src="testing/qunit-2.4.0.js"></script>
<script src="docs/js/jquery-latest.min.js"></script>
<script src="js/jquery.tablesorter.js"></script>
<script src="js/widgets/widget-filter.js"></script>

View File

@ -1,12 +1,12 @@
/*!
* QUnit 2.3.1
* QUnit 2.4.0
* https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2017-04-10T19:56Z
* Date: 2017-07-08T15:20Z
*/
/** Font Family and Sizes */

View File

@ -1,19 +1,20 @@
/*!
* QUnit 2.3.1
* QUnit 2.4.0
* https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2017-04-10T19:56Z
* Date: 2017-07-08T15:20Z
*/
(function (global$1) {
'use strict';
global$1 = 'default' in global$1 ? global$1['default'] : global$1;
global$1 = global$1 && 'default' in global$1 ? global$1['default'] : global$1;
var window = global$1.window;
var self$1 = global$1.self;
var console = global$1.console;
var setTimeout = global$1.setTimeout;
var clearTimeout = global$1.clearTimeout;
@ -226,10 +227,8 @@
case "Function":
case "Symbol":
return type.toLowerCase();
}
if ((typeof obj === "undefined" ? "undefined" : _typeof(obj)) === "object") {
return "object";
default:
return typeof obj === "undefined" ? "undefined" : _typeof(obj);
}
}
@ -587,7 +586,13 @@
return arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1));
}
return innerEquiv;
return function () {
var result = innerEquiv.apply(undefined, arguments);
// Release any retained objects
pairs.length = 0;
return result;
};
})();
/**
@ -634,7 +639,14 @@
name: "",
tests: [],
childModules: [],
testsRun: 0
testsRun: 0,
unskippedTestsRun: 0,
hooks: {
before: [],
beforeEach: [],
afterEach: [],
after: []
}
},
callbacks: {},
@ -1315,7 +1327,7 @@
return TestReport;
}();
var focused = false;
var focused$1 = false;
function Test(settings) {
var i, l;
@ -1323,12 +1335,30 @@
++Test.count;
this.expected = null;
extend(this, settings);
this.assertions = [];
this.semaphore = 0;
this.module = config.currentModule;
this.stack = sourceFromStacktrace(3);
this.steps = [];
this.timeout = undefined;
// If a module is skipped, all its tests and the tests of the child suites
// should be treated as skipped even if they are defined as `only` or `todo`.
// As for `todo` module, all its tests will be treated as `todo` except for
// tests defined as `skip` which will be left intact.
//
// So, if a test is defined as `todo` and is inside a skipped module, we should
// then treat that test as if was defined as `skip`.
if (this.module.skip) {
settings.skip = true;
settings.todo = false;
// Skipped tests should be left intact
} else if (this.module.todo && !settings.skip) {
settings.todo = true;
}
extend(this, settings);
this.testReport = new TestReport(settings.testName, this.module.suiteReport, {
todo: settings.todo,
@ -1347,7 +1377,8 @@
this.module.tests.push({
name: this.testName,
testId: this.testId
testId: this.testId,
skip: !!settings.skip
});
if (settings.skip) {
@ -1439,6 +1470,12 @@
function runTest(test) {
promise = test.callback.call(test.testEnvironment, test.assert);
test.resolvePromise(promise);
// If the test has a "lock" on it, but the timeout is 0, then we push a
// failure as the test should be synchronous.
if (test.timeout === 0 && test.semaphore !== 0) {
pushFailure("Test did not finish synchronously even though assert.timeout( 0 ) was used.", sourceFromStacktrace(2));
}
}
},
@ -1447,22 +1484,27 @@
},
queueHook: function queueHook(hook, hookName, hookOwner) {
var promise,
test = this;
return function runHook() {
var _this = this;
var callHook = function callHook() {
var promise = hook.call(_this.testEnvironment, _this.assert);
_this.resolvePromise(promise, hookName);
};
var runHook = function runHook() {
if (hookName === "before") {
if (hookOwner.testsRun !== 0) {
if (hookOwner.unskippedTestsRun !== 0) {
return;
}
test.preserveEnvironment = true;
_this.preserveEnvironment = true;
}
if (hookName === "after" && hookOwner.testsRun !== numberOfTests(hookOwner) - 1 && config.queue.length > 2) {
if (hookName === "after" && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && config.queue.length > 2) {
return;
}
config.current = test;
config.current = _this;
if (config.notrycatch) {
callHook();
return;
@ -1470,16 +1512,14 @@
try {
callHook();
} catch (error) {
test.pushFailure(hookName + " failed on " + test.testName + ": " + (error.message || error), extractStacktrace(error, 0));
}
function callHook() {
promise = hook.call(test.testEnvironment, test.assert);
test.resolvePromise(promise, hookName);
_this.pushFailure(hookName + " failed on " + _this.testName + ": " + (error.message || error), extractStacktrace(error, 0));
}
};
return runHook;
},
// Currently only used for module level hooks, can be used to add global level ones
hooks: function hooks(handler) {
var hooks = [];
@ -1488,8 +1528,11 @@
if (module.parentModule) {
processHooks(test, module.parentModule);
}
if (module.hooks && objectType(module.hooks[handler]) === "function") {
hooks.push(test.queueHook(module.hooks[handler], handler, module));
if (module.hooks[handler].length) {
for (var i = 0; i < module.hooks[handler].length; i++) {
hooks.push(test.queueHook(module.hooks[handler][i], handler, module));
}
}
}
@ -1497,9 +1540,11 @@
if (!this.skip) {
processHooks(this, this.module);
}
return hooks;
},
finish: function finish() {
config.current = this;
if (config.requireExpects && this.expected === null) {
@ -1532,7 +1577,7 @@
}
}
notifyTestsRan(module);
notifyTestsRan(module, skipped);
// Store result when possible
if (storage) {
@ -1857,7 +1902,7 @@
// Will be exposed as QUnit.test
function test(testName, callback) {
if (focused) {
if (focused$1) {
return;
}
@ -1870,7 +1915,7 @@
}
function todo(testName, callback) {
if (focused) {
if (focused$1) {
return;
}
@ -1885,7 +1930,7 @@
// Will be exposed as QUnit.skip
function skip(testName) {
if (focused) {
if (focused$1) {
return;
}
@ -1899,12 +1944,12 @@
// Will be exposed as QUnit.only
function only(testName, callback) {
if (focused) {
if (focused$1) {
return;
}
config.queue.length = 0;
focused = true;
focused$1 = true;
var newTest = new Test({
testName: testName,
@ -1916,20 +1961,29 @@
// Put a hold on processing and return a function that will release it.
function internalStop(test) {
var released = false;
test.semaphore += 1;
config.blocking = true;
// Set a recovery timeout, if so configured.
if (config.testTimeout && defined.setTimeout) {
clearTimeout(config.timeout);
config.timeout = setTimeout(function () {
pushFailure("Test timed out", sourceFromStacktrace(2));
internalRecover(test);
}, config.testTimeout);
if (defined.setTimeout) {
var timeoutDuration = void 0;
if (typeof test.timeout === "number") {
timeoutDuration = test.timeout;
} else if (typeof config.testTimeout === "number") {
timeoutDuration = config.testTimeout;
}
if (typeof timeoutDuration === "number" && timeoutDuration > 0) {
clearTimeout(config.timeout);
config.timeout = setTimeout(function () {
pushFailure("Test took longer than " + timeoutDuration + "ms; test timed out.", sourceFromStacktrace(2));
internalRecover(test);
}, timeoutDuration);
}
}
var released = false;
return function resume() {
if (released) {
return;
@ -1992,24 +2046,40 @@
}
}
function numberOfTests(module) {
var count = module.tests.length;
function collectTests(module) {
var tests = [].concat(module.tests);
var modules = [].concat(toConsumableArray(module.childModules));
// Do a breadth-first traversal of the child modules
while (modules.length) {
var nextModule = modules.shift();
count += nextModule.tests.length;
tests.push.apply(tests, nextModule.tests);
modules.push.apply(modules, toConsumableArray(nextModule.childModules));
}
return count;
return tests;
}
function notifyTestsRan(module) {
function numberOfTests(module) {
return collectTests(module).length;
}
function numberOfUnskippedTests(module) {
return collectTests(module).filter(function (test) {
return !test.skip;
}).length;
}
function notifyTestsRan(module, skipped) {
module.testsRun++;
if (!skipped) {
module.unskippedTestsRun++;
}
while (module = module.parentModule) {
module.testsRun++;
if (!skipped) {
module.unskippedTestsRun++;
}
}
}
@ -2040,10 +2110,19 @@
// Assert helpers
createClass(Assert, [{
key: "timeout",
value: function timeout(duration) {
if (typeof duration !== "number") {
throw new Error("You must pass a number as the duration to assert.timeout");
}
this.test.timeout = duration;
}
// Documents a "step", which is a string value, in a test as a passing assertion
createClass(Assert, [{
}, {
key: "step",
value: function step(message) {
var result = !!message;
@ -2119,7 +2198,7 @@
}, {
key: "push",
value: function push(result, actual, expected, message, negative) {
Logger.warn("assert.push is deprecated and will be removed in QUnit 3.0." + " Please use assert.pushResult instead (http://api.qunitjs.com/pushResult/).");
Logger.warn("assert.push is deprecated and will be removed in QUnit 3.0." + " Please use assert.pushResult instead (https://api.qunitjs.com/assert/pushResult).");
var currentAssert = this instanceof Assert ? this : config.current.assert;
return currentAssert.pushResult({
@ -2409,6 +2488,11 @@
});
QUnit.config.autostart = false;
}
// For Web/Service Workers
if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {
self$1.QUnit = QUnit;
}
}
var SuiteReport = function () {
@ -2549,6 +2633,7 @@
return false;
}
var focused = false;
var QUnit = {};
var globalSuite = new SuiteReport();
@ -2565,21 +2650,32 @@
QUnit.isLocal = !(defined.document && window.location.protocol !== "file:");
// Expose the current QUnit version
QUnit.version = "2.3.1";
QUnit.version = "2.4.0";
function createModule(name, testEnvironment) {
function createModule(name, testEnvironment, modifiers) {
var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;
var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
var skip$$1 = parentModule !== null && parentModule.skip || modifiers.skip;
var todo$$1 = parentModule !== null && parentModule.todo || modifiers.todo;
var module = {
name: moduleName,
parentModule: parentModule,
tests: [],
moduleId: generateHash(moduleName),
testsRun: 0,
unskippedTestsRun: 0,
childModules: [],
suiteReport: new SuiteReport(name, parentSuite)
suiteReport: new SuiteReport(name, parentSuite),
// Pass along `skip` and `todo` properties from parent module, in case
// there is one, to childs. And use own otherwise.
// This property will be used to mark own tests and tests of child suites
// as either `skipped` or `todo`.
skip: skip$$1,
todo: skip$$1 ? false : todo$$1
};
var env = {};
@ -2594,40 +2690,31 @@
return module;
}
extend(QUnit, {
on: on,
function processModule(name, options, executeNow) {
var modifiers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
// Call on start of module test to prepend name to all tests
module: function module(name, testEnvironment, executeNow) {
if (arguments.length === 2) {
if (objectType(testEnvironment) === "function") {
executeNow = testEnvironment;
testEnvironment = undefined;
}
}
var module = createModule(name, testEnvironment);
var module = createModule(name, options, modifiers);
// Move any hooks to a 'hooks' object
if (module.testEnvironment) {
module.hooks = {
before: module.testEnvironment.before,
beforeEach: module.testEnvironment.beforeEach,
afterEach: module.testEnvironment.afterEach,
after: module.testEnvironment.after
};
var testEnvironment = module.testEnvironment;
var hooks = module.hooks = {};
delete module.testEnvironment.before;
delete module.testEnvironment.beforeEach;
delete module.testEnvironment.afterEach;
delete module.testEnvironment.after;
setHookFromEnvironment(hooks, testEnvironment, "before");
setHookFromEnvironment(hooks, testEnvironment, "beforeEach");
setHookFromEnvironment(hooks, testEnvironment, "afterEach");
setHookFromEnvironment(hooks, testEnvironment, "after");
function setHookFromEnvironment(hooks, environment, name) {
var potentialHook = environment[name];
hooks[name] = typeof potentialHook === "function" ? [potentialHook] : [];
delete environment[name];
}
var moduleFns = {
before: setHook(module, "before"),
beforeEach: setHook(module, "beforeEach"),
afterEach: setHook(module, "afterEach"),
after: setHook(module, "after")
before: setHookFunction(module, "before"),
beforeEach: setHookFunction(module, "beforeEach"),
afterEach: setHookFunction(module, "afterEach"),
after: setHookFunction(module, "after")
};
var currentModule = config.currentModule;
@ -2640,7 +2727,71 @@
}
config.currentModule = module;
},
}
// TODO: extract this to a new file alongside its related functions
function module$1(name, options, executeNow) {
if (focused) {
return;
}
if (arguments.length === 2) {
if (objectType(options) === "function") {
executeNow = options;
options = undefined;
}
}
processModule(name, options, executeNow);
}
module$1.only = function () {
if (focused) {
return;
}
config.modules.length = 0;
config.queue.length = 0;
module$1.apply(undefined, arguments);
focused = true;
};
module$1.skip = function (name, options, executeNow) {
if (focused) {
return;
}
if (arguments.length === 2) {
if (objectType(options) === "function") {
executeNow = options;
options = undefined;
}
}
processModule(name, options, executeNow, { skip: true });
};
module$1.todo = function (name, options, executeNow) {
if (focused) {
return;
}
if (arguments.length === 2) {
if (objectType(options) === "function") {
executeNow = options;
options = undefined;
}
}
processModule(name, options, executeNow, { todo: true });
};
extend(QUnit, {
on: on,
module: module$1,
test: test,
@ -2777,13 +2928,9 @@
ProcessingQueue.advance();
}
function setHook(module, hookName) {
if (!module.hooks) {
module.hooks = {};
}
return function (callback) {
module.hooks[hookName] = callback;
function setHookFunction(module, hookName) {
return function setHook(callback) {
module.hooks[hookName].push(callback);
};
}
@ -3641,13 +3788,19 @@
message += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText(actual) + "</pre></td></tr>";
// Don't show diff if actual or expected are booleans
if (!/^(true|false)$/.test(actual) && !/^(true|false)$/.test(expected)) {
if (typeof details.actual === "number" && typeof details.expected === "number") {
if (!isNaN(details.actual) && !isNaN(details.expected)) {
showDiff = true;
diff = details.actual - details.expected;
diff = (diff > 0 ? "+" : "") + diff;
}
} else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {
diff = QUnit.diff(expected, actual);
// don't show diff if there is zero overlap
showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length;
}
// Don't show diff if expected and actual are totally different
if (showDiff) {
message += "<tr class='test-diff'><th>Diff: </th><td><pre>" + diff + "</pre></td></tr>";
}

View File

@ -982,13 +982,19 @@ jQuery(function($){
test has widget function
************************************************/
QUnit.test( 'has & remove zebra widget', function(assert) {
assert.expect(3);
var done = assert.async();
assert.expect(4);
c2.widgets = [ 'zebra' ];
$table2.trigger('applyWidgets');
$table2.trigger('applyWidgets', function() {
assert.equal( ts.hasWidget( table2, 'zebra'), true, 'table has zebra widget (using table element object)' );
assert.equal( ts.hasWidget( $table2, 'zebra'), true, 'table has zebra widget (using jQuery table object)' );
ts.removeWidget( table2, 'zebra' );
$table2.one( 'widgetRemoveEnd', function() {
assert.ok( true, 'widgetRemoveEnd fired');
assert.equal( zebra() && c2.widgets.length === 0, false, 'zebra removed' );
done();
});
ts.removeWidget( table2, 'zebra' );
});
});
/************************************************