Build: Add jscs checking & fix style issues

Thanks @Herst!
This commit is contained in:
Mottie 2015-07-22 23:29:51 -05:00
parent bd296c844f
commit 75de112ef6
63 changed files with 18095 additions and 17995 deletions

65
.jscsrc Normal file
View File

@ -0,0 +1,65 @@
{
"disallowDanglingUnderscores": true,
"disallowEmptyBlocks": true,
"disallowKeywords": [
"with"
],
"disallowMixedSpacesAndTabs": "smart",
"disallowMultipleLineBreaks": true,
"disallowMultipleLineStrings": true,
"disallowNewlineBeforeBlockStatements": true,
"disallowOperatorBeforeLineBreak": [
"."
],
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpaceBeforeBinaryOperators": [
","
],
"disallowSpaceBeforePostfixUnaryOperators": true,
"disallowSpacesInCallExpression": true,
"disallowTrailingComma": true,
"maximumLineLength": {
"allowRegex": true,
"allowUrlComments": true,
"tabSize": 2,
"value": 180
},
"requireBlocksOnNewline": 1,
"requireCommaBeforeLineBreak": true,
"requireCurlyBraces": [
"do"
],
"requireDollarBeforejQueryAssignment": true,
"requireDotNotation": true,
"requireLineFeedAtFileEnd": true,
"requireParenthesesAroundIIFE": true,
"requireSemicolons": true,
"requireSpaceAfterBinaryOperators": true,
"requireSpaceAfterKeywords": [
"if",
"else",
"for",
"while",
"do",
"switch",
"case",
"return",
"try",
"catch",
"typeof"
],
"requireSpaceAfterLineComment": true,
"requireSpaceBeforeBinaryOperators": true,
"requireSpacesInConditionalExpression": true,
"requireSpacesInForStatement": true,
"requireSpacesInsideArrayBrackets": "all",
"validateIndentation": {
"includeEmptyLines": false,
"value": "\t"
},
"validateQuoteMarks": {
"escape": true,
"mark": "'"
}
}

View File

@ -209,6 +209,26 @@ module.exports = function( grunt ) {
}
},
jscs: {
src: [
'addons/pager/*.js',
'!addons/pager/*.min.js',
'js/jquery.*.js',
'js/**/*.js',
'!js/_test-*.js',
'!js/jquery.tablesorter.combined.js',
'!js/jquery.tablesorter.widgets.js',
'!js/extras/jquery.dragtable.mod.js', // indents with spaces; keeping original formatting to make diffs easier
'!js/extras/jquery.metadata.js', // phasing this one out anyway
'!js/**/_test-*.js',
'!js/*.min.js',
'!js/**/semver*.js'
],
options: {
config: '.jscsrc'
}
},
jshint: {
files: {
src: [
@ -317,8 +337,9 @@ module.exports = function( grunt ) {
grunt.loadNpmTasks( 'grunt-contrib-copy' );
grunt.loadNpmTasks( 'grunt-contrib-watch' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
grunt.loadNpmTasks( 'grunt-jscs' );
grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
grunt.registerTask( 'test', [ 'jscs', 'jshint', 'qunit' ] );
tasks = [
'clean:build',

View File

@ -4,7 +4,7 @@
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($) {
"use strict";
'use strict';
/*jshint supernew:true */
var ts = $.tablesorter;
@ -176,13 +176,13 @@
// form the output string (can now get a new output string from the server)
s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || p.output : p.output )
// {page} = one-based index; {page+#} = zero based index +/- value
.replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
.replace(/\{page([\-+]\d+)?\}/gi, function(m, n){
return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
})
// {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
.replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
var len, indx,
str = m.replace(/[{}\s]/g,''),
str = m.replace(/[{}\s]/g, ''),
extra = str.split(':'),
data = p.ajaxData,
// return zero for default page/row numbers
@ -209,7 +209,7 @@
// rebind startRow/page inputs
$out.find('.ts-startRow, .ts-page').unbind('change' + namespace).bind('change' + namespace, function(){
var v = $(this).val(),
pg = $(this).hasClass('ts-startRow') ? Math.floor( v/p.size ) + 1 : v;
pg = $(this).hasClass('ts-startRow') ? Math.floor( v / p.size ) + 1 : v;
c.$table.trigger('pageSet' + namespace, [ pg ]);
});
}
@ -242,7 +242,7 @@
current_page = p.page + 1,
start_page = skip_set_size,
end_page = pg - skip_set_size,
option_pages = [1],
option_pages = [ 1 ],
// construct default options pages array
option_pages_start_page = (large_collection) ? skip_set_size : 1;
@ -286,7 +286,7 @@
option_pages = $.grep(option_pages, function(value, indx) {
return $.inArray(value, option_pages) === indx;
})
.sort(function(a,b) { return a - b; });
.sort(function(a, b) { return a - b; });
return option_pages;
},
@ -376,7 +376,7 @@
renderAjax = function(data, table, p, xhr, exception){
// process data
if ( typeof(p.ajaxProcessing) === "function" ) {
if ( typeof p.ajaxProcessing === 'function' ) {
// ajaxProcessing result: [ total, rows, headers ]
var i, j, t, hsh, $f, $sh, $headers, $h, icon, th, d, l, rr_count, len,
c = table.config,
@ -483,7 +483,7 @@
p.last.currentFilters = p.currentFilters;
p.last.sortList = (c.sortList || []).join(',');
updatePageDisplay(table, p, false);
$table.trigger('updateCache', [function(){
$table.trigger('updateCache', [ function(){
if (p.initialized) {
// apply widgets after table has rendered & after a delay to prevent
// multiple applyWidget blocking code from blocking this trigger
@ -495,9 +495,9 @@
.trigger('applyWidgets')
.trigger('pagerChange', p);
updatePageDisplay(table, p, true);
}, 0);
}, 0);
}
}]);
} ]);
}
if (!p.initialized) {
@ -555,7 +555,7 @@
c = table.config,
url = (p.ajaxUrl) ? p.ajaxUrl
// allow using "{page+1}" in the url string to switch to a non-zero based index
.replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{page([\-+]\d+)?\}/, function(s, n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{size\}/g, p.size) : '',
sortList = c.sortList,
filterList = p.currentFilters || $(table).data('lastSearch') || [],
@ -584,7 +584,7 @@
url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
p.currentFilters = filterList;
}
if ( typeof(p.customAjaxUrl) === "function" ) {
if ( typeof p.customAjaxUrl === 'function' ) {
url = p.customAjaxUrl(table, url);
}
if (c.debug) {
@ -940,13 +940,13 @@
changeHeight(table, p);
updatePageDisplay(table, p, true);
})
.bind('pageSize refreshComplete '.split(' ').join(namespace + ' '), function(e,v){
.bind('pageSize refreshComplete '.split(' ').join(namespace + ' '), function(e, v){
e.stopPropagation();
setPageSize(table, parseInt(v, 10) || p.settings.size || 10, p);
hideRows(table, p);
updatePageDisplay(table, p, false);
})
.bind('pageSet pagerUpdate '.split(' ').join(namespace + ' '), function(e,v){
.bind('pageSet pagerUpdate '.split(' ').join(namespace + ' '), function(e, v){
e.stopPropagation();
// force pager refresh
if (e.type === 'pagerUpdate') {
@ -973,7 +973,7 @@
ts.log('Pager: >> Container not found');
}
pager.find(ctrls.join(','))
.attr("tabindex", 0)
.attr('tabindex', 0)
.unbind('click' + namespace)
.bind('click' + namespace, function(e){
e.stopPropagation();
@ -1024,17 +1024,18 @@
$t.trigger('pagerBeforeInitialized', p);
enablePager(table, p, false);
if ( typeof(p.ajaxUrl) === 'string' ) {
if ( typeof p.ajaxUrl === 'string' ) {
// ajax pager; interact with database
p.ajax = true;
//When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
// When filtering with ajax, allow only custom filtering function, disable default
// filtering since it will be done server side.
c.widgetOptions.filter_serversideFiltering = true;
c.serverSideSorting = true;
moveToPage(table, p);
} else {
p.ajax = false;
// Regular pager; all rows stored in memory
$(this).trigger("appendCache", true);
$(this).trigger('appendCache', true);
hideRowsSetup(table, p);
}
@ -1087,9 +1088,9 @@
}
};
// extend plugin scope
$.fn.extend({
tablesorterPager: $.tablesorterPager.construct
});
// extend plugin scope
$.fn.extend({
tablesorterPager: $.tablesorterPager.construct
});
})(jQuery);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -198,7 +198,7 @@
// node could be a jquery object
// http://jsperf.com/jquery-vs-instanceof-jquery/2
$node = node.jquery ? node : $(node);
if (typeof(t) === 'string') {
if (typeof t === 'string') {
// check data-attribute first when set to 'basic'; don't use node.innerText - it's really slow!
// http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/
if ( t === 'basic' && typeof ( te = $node.attr(c.textAttribute) ) !== 'undefined' ) {
@ -206,7 +206,7 @@
}
return $.trim( node.textContent || $node.text() );
} else {
if (typeof(t) === 'function') {
if (typeof t === 'function') {
return $.trim( t($node[0], c.table, cellIndex) );
} else if (typeof (te = ts.getColumnData( c.table, t, cellIndex )) === 'function') {
return $.trim( te($node[0], c.table, cellIndex) );
@ -266,7 +266,7 @@
// make sure txt is a string (extractor may have converted it)
parser.format( '' + txt, c.table, cell, colIndex );
if ( c.ignoreCase && typeof val === 'string' ) {
val = val.toLowerCase();
val = val.toLowerCase();
}
}
return val;
@ -510,20 +510,22 @@
// set up header template
t = c.headerTemplate.replace(/\{content\}/g, $t.html()).replace(/\{icon\}/g, $t.find('.' + ts.css.icon).length ? '' : i);
if (c.onRenderTemplate) {
h = c.onRenderTemplate.apply($t, [index, t]);
h = c.onRenderTemplate.apply( $t, [ index, t ] );
if (h && typeof h === 'string') { t = h; } // only change t if something is returned
}
$t.html('<div class="' + ts.css.headerIn + '">' + t + '</div>'); // faster than wrapInner
}
if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index, c, c.$table]); }
if (c.onRenderHeader) { c.onRenderHeader.apply( $t, [ index, c, c.$table ] ); }
// *** remove this.column value if no conflicts found
elem.column = parseInt( $t.attr('data-column'), 10);
elem.order = formatSortingOrder( ts.getData($t, ch, 'sortInitialOrder') || c.sortInitialOrder ) ? [1,0,2] : [0,1,2];
elem.order = formatSortingOrder( ts.getData( $t, ch, 'sortInitialOrder' ) || c.sortInitialOrder ) ?
[ 1, 0, 2 ] : // desc, asc, unsorted
[ 0, 1, 2 ]; // asc, desc, unsorted
elem.count = -1; // set to -1 because clicking on the header automatically adds one
elem.lockedOrder = false;
lock = ts.getData($t, ch, 'lockedOrder') || false;
if (typeof lock !== 'undefined' && lock !== false) {
elem.order = elem.lockedOrder = formatSortingOrder(lock) ? [1,1,1] : [0,0,0];
elem.order = elem.lockedOrder = formatSortingOrder(lock) ? [ 1, 1, 1 ] : [ 0, 0, 0 ];
}
$t.addClass(ts.css.header + ' ' + c.cssHeader);
// add cell to headerList
@ -593,9 +595,9 @@
list = c.sortList,
len = list.length,
none = ts.css.sortNone + ' ' + c.cssNone,
css = [ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc],
css = [ ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc ],
cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ],
aria = ['ascending', 'descending'],
aria = [ 'ascending', 'descending' ],
// find the footer
$t = $(table).find('tfoot tr').children()
.add( $( c.namespace + '_extra_headers' ) )
@ -665,7 +667,7 @@
dir = ('' + val[1]).match(/^(1|d|s|o|n)/);
dir = dir ? dir[0] : '';
// 0/(a)sc (default), 1/(d)esc, (s)ame, (o)pposite, (n)ext
switch(dir) {
switch (dir) {
case '1': case 'd': // descending
dir = 1;
break;
@ -741,11 +743,11 @@
// add column to sort list
order = cell.order[cell.count];
if (order < 2) {
c.sortList.push([indx, order]);
c.sortList.push([ indx, order ]);
// add other columns if header spans across multiple
if (cell.colSpan > 1) {
for (col = 1; col < cell.colSpan; col++) {
c.sortList.push([indx + col, order]);
c.sortList.push([ indx + col, order ]);
}
}
}
@ -756,7 +758,7 @@
for (col = 0; col < c.sortAppend.length; col++) {
s = ts.isValueInArray(c.sortAppend[col][0], c.sortList);
if (s >= 0) {
c.sortList.splice(s,1);
c.sortList.splice(s, 1);
}
}
}
@ -770,7 +772,7 @@
// order.count seems to be incorrect when compared to cell.count
s[1] = order.order[cell.count];
if (s[1] === 2) {
c.sortList.splice(col,1);
c.sortList.splice(col, 1);
order.count = -1;
}
}
@ -779,11 +781,11 @@
// add column to sort list array
order = cell.order[cell.count];
if (order < 2) {
c.sortList.push([indx, order]);
c.sortList.push([ indx, order ]);
// add other columns if header spans across multiple
if (cell.colSpan > 1) {
for (col = 1; col < cell.colSpan; col++) {
c.sortList.push([indx + col, order]);
c.sortList.push([ indx + col, order ]);
}
}
}
@ -857,10 +859,10 @@
x = dir ? a : b;
y = dir ? b : a;
// text sort function
if (typeof(cts) === 'function') {
if (typeof cts === 'function') {
// custom OVERALL text sorter
sort = cts(x[col], y[col], dir, col, table);
} else if (typeof(cts) === 'object' && cts.hasOwnProperty(col)) {
} else if (typeof cts === 'object' && cts.hasOwnProperty(col)) {
// custom text sorter for a SPECIFIC COLUMN
sort = cts[col](x[col], y[col], dir, col, table);
} else {
@ -893,14 +895,14 @@
// this will catch spamming of the updateCell method
if (resrt !== false && !c.serverSideSorting && !c.table.isProcessing) {
if (sl.length) {
c.$table.trigger('sorton', [sl, function(){
c.$table.trigger('sorton', [ sl, function(){
resortComplete(c, callback);
}, true]);
}, true ]);
} else {
c.$table.trigger('sortReset', [function(){
c.$table.trigger('sortReset', [ function(){
resortComplete(c, callback);
ts.applyWidget(c.table, false);
}]);
} ]);
}
} else {
resortComplete(c, callback);
@ -1100,10 +1102,10 @@
ts.construct = function(settings) {
return this.each(function() {
var table = this,
// merge & extend config options
c = $.extend(true, {}, ts.defaults, settings, ts.instanceMethods);
// save initial settings
c.originalSettings = settings;
// merge & extend config options
c = $.extend(true, {}, ts.defaults, settings, ts.instanceMethods);
// save initial settings
c.originalSettings = settings;
// create a table from data (build table widget)
if (!table.hasInitialized && ts.buildTable && this.nodeName !== 'TABLE') {
// return the table (in case the original target is the table's container)
@ -1158,7 +1160,7 @@
c.namespace = '.tablesorter' + Math.random().toString(16).slice(2);
} else {
// make sure namespace starts with a period & doesn't have weird characters
c.namespace = '.' + c.namespace.replace(/\W/g,'');
c.namespace = '.' + c.namespace.replace(/\W/g, '');
}
c.$table.children().children('tr').attr('role', 'row');
@ -1202,7 +1204,7 @@
ts.applyWidget(table, true);
// if user has supplied a sort list to constructor
if (c.sortList.length > 0) {
$table.trigger('sorton', [c.sortList, {}, !c.initWidgets, true]);
$table.trigger('sorton', [ c.sortList, {}, !c.initWidgets, true ]);
} else {
setHeadersCss(table);
if (c.initWidgets) {
@ -1241,22 +1243,22 @@
table = $(table)[0];
var overallWidth, percent, $tbodies, len, index,
c = table.config,
colgroup = c.$table.children('colgroup');
$colgroup = c.$table.children('colgroup');
// remove plugin-added colgroup, in case we need to refresh the widths
if (colgroup.length && colgroup.hasClass(ts.css.colgroup)) {
colgroup.remove();
if ($colgroup.length && $colgroup.hasClass(ts.css.colgroup)) {
$colgroup.remove();
}
if (c.widthFixed && c.$table.children('colgroup').length === 0) {
colgroup = $('<colgroup class="' + ts.css.colgroup + '">');
$colgroup = $('<colgroup class="' + ts.css.colgroup + '">');
overallWidth = c.$table.width();
// only add col for visible columns - fixes #371
$tbodies = c.$tbodies.find('tr:first').children(':visible'); //.each(function()
$tbodies = c.$tbodies.find('tr:first').children(':visible'); // .each(function()
len = $tbodies.length;
for ( index = 0; index < len; index++ ) {
percent = parseInt( ( $tbodies.eq( index ).width() / overallWidth ) * 1000, 10 ) / 10 + '%';
colgroup.append( $('<col>').css('width', percent) );
$colgroup.append( $('<col>').css('width', percent) );
}
c.$table.prepend(colgroup);
c.$table.prepend($colgroup);
}
};
@ -1303,12 +1305,12 @@
cellId = rowIndex + '-' + $cell.index();
rowSpan = cell.rowSpan || 1;
colSpan = cell.colSpan || 1;
if (typeof(matrix[rowIndex]) === 'undefined') {
if (typeof matrix[rowIndex] === 'undefined') {
matrix[rowIndex] = [];
}
// Find first available column in the first row
for (k = 0; k < matrix[rowIndex].length + 1; k++) {
if (typeof(matrix[rowIndex][k]) === 'undefined') {
if (typeof matrix[rowIndex][k] === 'undefined') {
firstAvailCol = k;
break;
}
@ -1317,7 +1319,7 @@
// add data-column
$cell.attr({ 'data-column' : firstAvailCol }); // 'data-row' : rowIndex
for (k = rowIndex; k < rowIndex + rowSpan; k++) {
if (typeof(matrix[k]) === 'undefined') {
if (typeof matrix[k] === 'undefined') {
matrix[k] = [];
}
matrixrow = matrix[k];
@ -1333,10 +1335,10 @@
// *** Process table ***
// add processing indicator
ts.isProcessing = function(table, toggle, $ths) {
table = $(table);
var c = table[0].config,
$table = $(table);
var c = $table[0].config,
// default to all headers
$h = $ths || table.find('.' + ts.css.header);
$h = $ths || $table.find('.' + ts.css.header);
if (toggle) {
// don't use sortList if custom $ths used
if (typeof $ths !== 'undefined' && c.sortList.length > 0) {
@ -1346,9 +1348,9 @@
return this.sortDisabled ? false : ts.isValueInArray( parseFloat($(this).attr('data-column')), c.sortList) >= 0;
});
}
table.add($h).addClass(ts.css.processing + ' ' + c.cssProcessing);
$table.add($h).addClass(ts.css.processing + ' ' + c.cssProcessing);
} else {
table.add($h).removeClass(ts.css.processing + ' ' + c.cssProcessing);
$table.add($h).removeClass(ts.css.processing + ' ' + c.cssProcessing);
}
};
@ -1478,8 +1480,8 @@
$f = $t.find('tfoot:first > tr').children('th, td');
if (removeClasses === false && $.inArray('uitheme', c.widgets) >= 0) {
// reapply uitheme classes, in case we want to maintain appearance
$t.trigger('applyWidgetId', ['uitheme']);
$t.trigger('applyWidgetId', ['zebra']);
$t.trigger('applyWidgetId', [ 'uitheme' ]);
$t.trigger('applyWidgetId', [ 'zebra' ]);
}
// remove widget added rows, just in case
$h.find('tr').not($r).remove();
@ -1491,7 +1493,7 @@
.removeData('tablesorter')
.unbind( events.replace(/\s+/g, ' ') );
c.$headers.add($f)
.removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone].join(' ') )
.removeClass( [ ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone ].join(' ') )
.removeAttr('data-column')
.removeAttr('aria-label')
.attr('aria-disabled', 'true');
@ -1697,8 +1699,8 @@
};
ts.hasWidget = function(table, name){
table = $(table);
return table.length && table[0].config && table[0].config.widgetInit[name] || false;
$table = $(table);
return $table.length && $table[0].config && $table[0].config.widgetInit[name] || false;
};
ts.getWidgetById = function(name) {
@ -1738,7 +1740,7 @@
if (c.debug) { time = new Date(); }
// look for widgets to apply from in table class
// stop using \b otherwise this matches 'ui-widget-content' & adds 'content' widget
wd = new RegExp( '\\s' + c.widgetClass.replace( /\{name\}/i, '([\\w-]+)' )+ '\\s', 'g' );
wd = new RegExp( '\\s' + c.widgetClass.replace( /\{name\}/i, '([\\w-]+)' ) + '\\s', 'g' );
if ( tableClass.match( wd ) ) {
// extract out the widget id from the table class (widget id's can include dashes)
w = tableClass.match( wd );
@ -1946,13 +1948,13 @@
typeof table !== 'undefined' ? table : true;
if (t) {
// US Format - 1,234,567.89 -> 1234567.89
s = s.replace(/,/g,'');
s = s.replace(/,/g, '');
} else {
// German Format = 1.234.567,89 -> 1234567.89
// French Format = 1 234 567,89 -> 1234567.89
s = s.replace(/[\s|\.]/g,'').replace(/,/g,'.');
s = s.replace(/[\s|\.]/g, '').replace(/,/g, '.');
}
if(/^\s*\([.\d]+\)/.test(s)) {
if (/^\s*\([.\d]+\)/.test(s)) {
// make (#) into a negative number -> (10) = -10
s = s.replace(/^\s*\(([.\d]+)\)/, '-$1');
}
@ -2020,7 +2022,7 @@
ts.addParser({
id: 'currency',
is: function(s) {
return (/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/).test((s || '').replace(/[+\-,. ]/g,'')); // £$€¤¥¢
return (/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/).test((s || '').replace(/[+\-,. ]/g, '')); // £$€¤¥¢
},
format: function(s, table) {
var n = ts.formatFloat((s || '').replace(/[^\w,. \-()]/g, ''), table);
@ -2095,7 +2097,7 @@
id: 'shortDate', // 'mmddyyyy', 'ddmmyyyy' or 'yyyymmdd'
is: function(s) {
// testing for ##-##-#### or ####-##-##, so it's not perfect; time can be included
return (/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/).test((s || '').replace(/\s+/g,' ').replace(/[\-.,]/g, '/'));
return (/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/).test((s || '').replace(/\s+/g, ' ').replace(/[\-.,]/g, '/'));
},
format: function(s, table, cell, cellIndex) {
if (s) {

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
/*! Parser: distance */
!function(a){"use strict";var b=a.tablesorter;b.symbolRegex=/[\u215b\u215c\u215d\u215e\u00bc\u00bd\u00be]/g,b.processFractions=function(c,d){if(c){var e,f=0;c=a.trim(c.replace(/\"/,"")),/\s/.test(c)&&(f=b.formatFloat(c.split(" ")[0],d),c=a.trim(c.substring(c.indexOf(" "),c.length))),/\//g.test(c)?(e=c.split("/"),c=f+parseInt(e[0],10)/parseInt(e[1]||1,10)):b.symbolRegex.test(c)&&(c=f+c.replace(b.symbolRegex,function(a){return{"⅛":".125","⅜":".375","⅝":".625","⅞":".875","¼":".25","½":".5","¾":".75"}[a]}))}return c||0},a.tablesorter.addParser({id:"distance",is:function(){return!1},format:function(a,c){if(""===a)return"";var d=/^\s*\S*(\s+\S+)?\s*\'/.test(a)?a.split("'"):[0,a],e=b.processFractions(d[0],c),f=b.processFractions(d[1],c);return/[\'\"]/.test(a)?parseFloat(e)+(parseFloat(f)/12||0):parseFloat(e)+parseFloat(f)},type:"numeric"})}(jQuery);
!function(a){"use strict";var b=a.tablesorter;b.symbolRegex=/[\u215b\u215c\u215d\u215e\u00bc\u00bd\u00be]/g,b.processFractions=function(c,d){if(c){var e,f=0;c=a.trim(c.replace(/\"/,"")),/\s/.test(c)&&(f=b.formatFloat(c.split(" ")[0],d),c=a.trim(c.substring(c.indexOf(" "),c.length))),/\//g.test(c)?(e=c.split("/"),c=f+parseInt(e[0],10)/parseInt(e[1]||1,10)):b.symbolRegex.test(c)&&(c=f+c.replace(b.symbolRegex,function(a){return{"⅛":".125","⅜":".375","⅝":".625","⅞":".875","¼":".25","½":".5","¾":".75"}[a]}))}return c||0},a.tablesorter.addParser({id:"distance",is:function(){return!1},format:function(a,c){if(""===a)return"";var d=/^\s*\S*(\s+\S+)?\s*\'/.test(a)?a.split(/\'/):[0,a],e=b.processFractions(d[0],c),f=b.processFractions(d[1],c);return/[\'\"]/.test(a)?parseFloat(e)+(parseFloat(f)/12||0):parseFloat(e)+parseFloat(f)},type:"numeric"})}(jQuery);

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 it is too large Load Diff

View File

@ -188,7 +188,7 @@
// node could be a jquery object
// http://jsperf.com/jquery-vs-instanceof-jquery/2
$node = node.jquery ? node : $(node);
if (typeof(t) === 'string') {
if (typeof t === 'string') {
// check data-attribute first when set to 'basic'; don't use node.innerText - it's really slow!
// http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/
if ( t === 'basic' && typeof ( te = $node.attr(c.textAttribute) ) !== 'undefined' ) {
@ -196,7 +196,7 @@
}
return $.trim( node.textContent || $node.text() );
} else {
if (typeof(t) === 'function') {
if (typeof t === 'function') {
return $.trim( t($node[0], c.table, cellIndex) );
} else if (typeof (te = ts.getColumnData( c.table, t, cellIndex )) === 'function') {
return $.trim( te($node[0], c.table, cellIndex) );
@ -256,7 +256,7 @@
// make sure txt is a string (extractor may have converted it)
parser.format( '' + txt, c.table, cell, colIndex );
if ( c.ignoreCase && typeof val === 'string' ) {
val = val.toLowerCase();
val = val.toLowerCase();
}
}
return val;
@ -500,20 +500,22 @@
// set up header template
t = c.headerTemplate.replace(/\{content\}/g, $t.html()).replace(/\{icon\}/g, $t.find('.' + ts.css.icon).length ? '' : i);
if (c.onRenderTemplate) {
h = c.onRenderTemplate.apply($t, [index, t]);
h = c.onRenderTemplate.apply( $t, [ index, t ] );
if (h && typeof h === 'string') { t = h; } // only change t if something is returned
}
$t.html('<div class="' + ts.css.headerIn + '">' + t + '</div>'); // faster than wrapInner
}
if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index, c, c.$table]); }
if (c.onRenderHeader) { c.onRenderHeader.apply( $t, [ index, c, c.$table ] ); }
// *** remove this.column value if no conflicts found
elem.column = parseInt( $t.attr('data-column'), 10);
elem.order = formatSortingOrder( ts.getData($t, ch, 'sortInitialOrder') || c.sortInitialOrder ) ? [1,0,2] : [0,1,2];
elem.order = formatSortingOrder( ts.getData( $t, ch, 'sortInitialOrder' ) || c.sortInitialOrder ) ?
[ 1, 0, 2 ] : // desc, asc, unsorted
[ 0, 1, 2 ]; // asc, desc, unsorted
elem.count = -1; // set to -1 because clicking on the header automatically adds one
elem.lockedOrder = false;
lock = ts.getData($t, ch, 'lockedOrder') || false;
if (typeof lock !== 'undefined' && lock !== false) {
elem.order = elem.lockedOrder = formatSortingOrder(lock) ? [1,1,1] : [0,0,0];
elem.order = elem.lockedOrder = formatSortingOrder(lock) ? [ 1, 1, 1 ] : [ 0, 0, 0 ];
}
$t.addClass(ts.css.header + ' ' + c.cssHeader);
// add cell to headerList
@ -583,9 +585,9 @@
list = c.sortList,
len = list.length,
none = ts.css.sortNone + ' ' + c.cssNone,
css = [ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc],
css = [ ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc ],
cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ],
aria = ['ascending', 'descending'],
aria = [ 'ascending', 'descending' ],
// find the footer
$t = $(table).find('tfoot tr').children()
.add( $( c.namespace + '_extra_headers' ) )
@ -655,7 +657,7 @@
dir = ('' + val[1]).match(/^(1|d|s|o|n)/);
dir = dir ? dir[0] : '';
// 0/(a)sc (default), 1/(d)esc, (s)ame, (o)pposite, (n)ext
switch(dir) {
switch (dir) {
case '1': case 'd': // descending
dir = 1;
break;
@ -731,11 +733,11 @@
// add column to sort list
order = cell.order[cell.count];
if (order < 2) {
c.sortList.push([indx, order]);
c.sortList.push([ indx, order ]);
// add other columns if header spans across multiple
if (cell.colSpan > 1) {
for (col = 1; col < cell.colSpan; col++) {
c.sortList.push([indx + col, order]);
c.sortList.push([ indx + col, order ]);
}
}
}
@ -746,7 +748,7 @@
for (col = 0; col < c.sortAppend.length; col++) {
s = ts.isValueInArray(c.sortAppend[col][0], c.sortList);
if (s >= 0) {
c.sortList.splice(s,1);
c.sortList.splice(s, 1);
}
}
}
@ -760,7 +762,7 @@
// order.count seems to be incorrect when compared to cell.count
s[1] = order.order[cell.count];
if (s[1] === 2) {
c.sortList.splice(col,1);
c.sortList.splice(col, 1);
order.count = -1;
}
}
@ -769,11 +771,11 @@
// add column to sort list array
order = cell.order[cell.count];
if (order < 2) {
c.sortList.push([indx, order]);
c.sortList.push([ indx, order ]);
// add other columns if header spans across multiple
if (cell.colSpan > 1) {
for (col = 1; col < cell.colSpan; col++) {
c.sortList.push([indx + col, order]);
c.sortList.push([ indx + col, order ]);
}
}
}
@ -847,10 +849,10 @@
x = dir ? a : b;
y = dir ? b : a;
// text sort function
if (typeof(cts) === 'function') {
if (typeof cts === 'function') {
// custom OVERALL text sorter
sort = cts(x[col], y[col], dir, col, table);
} else if (typeof(cts) === 'object' && cts.hasOwnProperty(col)) {
} else if (typeof cts === 'object' && cts.hasOwnProperty(col)) {
// custom text sorter for a SPECIFIC COLUMN
sort = cts[col](x[col], y[col], dir, col, table);
} else {
@ -883,14 +885,14 @@
// this will catch spamming of the updateCell method
if (resrt !== false && !c.serverSideSorting && !c.table.isProcessing) {
if (sl.length) {
c.$table.trigger('sorton', [sl, function(){
c.$table.trigger('sorton', [ sl, function(){
resortComplete(c, callback);
}, true]);
}, true ]);
} else {
c.$table.trigger('sortReset', [function(){
c.$table.trigger('sortReset', [ function(){
resortComplete(c, callback);
ts.applyWidget(c.table, false);
}]);
} ]);
}
} else {
resortComplete(c, callback);
@ -1090,10 +1092,10 @@
ts.construct = function(settings) {
return this.each(function() {
var table = this,
// merge & extend config options
c = $.extend(true, {}, ts.defaults, settings, ts.instanceMethods);
// save initial settings
c.originalSettings = settings;
// merge & extend config options
c = $.extend(true, {}, ts.defaults, settings, ts.instanceMethods);
// save initial settings
c.originalSettings = settings;
// create a table from data (build table widget)
if (!table.hasInitialized && ts.buildTable && this.nodeName !== 'TABLE') {
// return the table (in case the original target is the table's container)
@ -1148,7 +1150,7 @@
c.namespace = '.tablesorter' + Math.random().toString(16).slice(2);
} else {
// make sure namespace starts with a period & doesn't have weird characters
c.namespace = '.' + c.namespace.replace(/\W/g,'');
c.namespace = '.' + c.namespace.replace(/\W/g, '');
}
c.$table.children().children('tr').attr('role', 'row');
@ -1192,7 +1194,7 @@
ts.applyWidget(table, true);
// if user has supplied a sort list to constructor
if (c.sortList.length > 0) {
$table.trigger('sorton', [c.sortList, {}, !c.initWidgets, true]);
$table.trigger('sorton', [ c.sortList, {}, !c.initWidgets, true ]);
} else {
setHeadersCss(table);
if (c.initWidgets) {
@ -1231,22 +1233,22 @@
table = $(table)[0];
var overallWidth, percent, $tbodies, len, index,
c = table.config,
colgroup = c.$table.children('colgroup');
$colgroup = c.$table.children('colgroup');
// remove plugin-added colgroup, in case we need to refresh the widths
if (colgroup.length && colgroup.hasClass(ts.css.colgroup)) {
colgroup.remove();
if ($colgroup.length && $colgroup.hasClass(ts.css.colgroup)) {
$colgroup.remove();
}
if (c.widthFixed && c.$table.children('colgroup').length === 0) {
colgroup = $('<colgroup class="' + ts.css.colgroup + '">');
$colgroup = $('<colgroup class="' + ts.css.colgroup + '">');
overallWidth = c.$table.width();
// only add col for visible columns - fixes #371
$tbodies = c.$tbodies.find('tr:first').children(':visible'); //.each(function()
$tbodies = c.$tbodies.find('tr:first').children(':visible'); // .each(function()
len = $tbodies.length;
for ( index = 0; index < len; index++ ) {
percent = parseInt( ( $tbodies.eq( index ).width() / overallWidth ) * 1000, 10 ) / 10 + '%';
colgroup.append( $('<col>').css('width', percent) );
$colgroup.append( $('<col>').css('width', percent) );
}
c.$table.prepend(colgroup);
c.$table.prepend($colgroup);
}
};
@ -1293,12 +1295,12 @@
cellId = rowIndex + '-' + $cell.index();
rowSpan = cell.rowSpan || 1;
colSpan = cell.colSpan || 1;
if (typeof(matrix[rowIndex]) === 'undefined') {
if (typeof matrix[rowIndex] === 'undefined') {
matrix[rowIndex] = [];
}
// Find first available column in the first row
for (k = 0; k < matrix[rowIndex].length + 1; k++) {
if (typeof(matrix[rowIndex][k]) === 'undefined') {
if (typeof matrix[rowIndex][k] === 'undefined') {
firstAvailCol = k;
break;
}
@ -1307,7 +1309,7 @@
// add data-column
$cell.attr({ 'data-column' : firstAvailCol }); // 'data-row' : rowIndex
for (k = rowIndex; k < rowIndex + rowSpan; k++) {
if (typeof(matrix[k]) === 'undefined') {
if (typeof matrix[k] === 'undefined') {
matrix[k] = [];
}
matrixrow = matrix[k];
@ -1323,10 +1325,10 @@
// *** Process table ***
// add processing indicator
ts.isProcessing = function(table, toggle, $ths) {
table = $(table);
var c = table[0].config,
$table = $(table);
var c = $table[0].config,
// default to all headers
$h = $ths || table.find('.' + ts.css.header);
$h = $ths || $table.find('.' + ts.css.header);
if (toggle) {
// don't use sortList if custom $ths used
if (typeof $ths !== 'undefined' && c.sortList.length > 0) {
@ -1336,9 +1338,9 @@
return this.sortDisabled ? false : ts.isValueInArray( parseFloat($(this).attr('data-column')), c.sortList) >= 0;
});
}
table.add($h).addClass(ts.css.processing + ' ' + c.cssProcessing);
$table.add($h).addClass(ts.css.processing + ' ' + c.cssProcessing);
} else {
table.add($h).removeClass(ts.css.processing + ' ' + c.cssProcessing);
$table.add($h).removeClass(ts.css.processing + ' ' + c.cssProcessing);
}
};
@ -1468,8 +1470,8 @@
$f = $t.find('tfoot:first > tr').children('th, td');
if (removeClasses === false && $.inArray('uitheme', c.widgets) >= 0) {
// reapply uitheme classes, in case we want to maintain appearance
$t.trigger('applyWidgetId', ['uitheme']);
$t.trigger('applyWidgetId', ['zebra']);
$t.trigger('applyWidgetId', [ 'uitheme' ]);
$t.trigger('applyWidgetId', [ 'zebra' ]);
}
// remove widget added rows, just in case
$h.find('tr').not($r).remove();
@ -1481,7 +1483,7 @@
.removeData('tablesorter')
.unbind( events.replace(/\s+/g, ' ') );
c.$headers.add($f)
.removeClass( [ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone].join(' ') )
.removeClass( [ ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone ].join(' ') )
.removeAttr('data-column')
.removeAttr('aria-label')
.attr('aria-disabled', 'true');
@ -1687,8 +1689,8 @@
};
ts.hasWidget = function(table, name){
table = $(table);
return table.length && table[0].config && table[0].config.widgetInit[name] || false;
$table = $(table);
return $table.length && $table[0].config && $table[0].config.widgetInit[name] || false;
};
ts.getWidgetById = function(name) {
@ -1728,7 +1730,7 @@
if (c.debug) { time = new Date(); }
// look for widgets to apply from in table class
// stop using \b otherwise this matches 'ui-widget-content' & adds 'content' widget
wd = new RegExp( '\\s' + c.widgetClass.replace( /\{name\}/i, '([\\w-]+)' )+ '\\s', 'g' );
wd = new RegExp( '\\s' + c.widgetClass.replace( /\{name\}/i, '([\\w-]+)' ) + '\\s', 'g' );
if ( tableClass.match( wd ) ) {
// extract out the widget id from the table class (widget id's can include dashes)
w = tableClass.match( wd );
@ -1936,13 +1938,13 @@
typeof table !== 'undefined' ? table : true;
if (t) {
// US Format - 1,234,567.89 -> 1234567.89
s = s.replace(/,/g,'');
s = s.replace(/,/g, '');
} else {
// German Format = 1.234.567,89 -> 1234567.89
// French Format = 1 234 567,89 -> 1234567.89
s = s.replace(/[\s|\.]/g,'').replace(/,/g,'.');
s = s.replace(/[\s|\.]/g, '').replace(/,/g, '.');
}
if(/^\s*\([.\d]+\)/.test(s)) {
if (/^\s*\([.\d]+\)/.test(s)) {
// make (#) into a negative number -> (10) = -10
s = s.replace(/^\s*\(([.\d]+)\)/, '-$1');
}
@ -2010,7 +2012,7 @@
ts.addParser({
id: 'currency',
is: function(s) {
return (/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/).test((s || '').replace(/[+\-,. ]/g,'')); // £$€¤¥¢
return (/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/).test((s || '').replace(/[+\-,. ]/g, '')); // £$€¤¥¢
},
format: function(s, table) {
var n = ts.formatFloat((s || '').replace(/[^\w,. \-()]/g, ''), table);
@ -2085,7 +2087,7 @@
id: 'shortDate', // 'mmddyyyy', 'ddmmyyyy' or 'yyyymmdd'
is: function(s) {
// testing for ##-##-#### or ####-##-##, so it's not perfect; time can be included
return (/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/).test((s || '').replace(/\s+/g,' ').replace(/[\-.,]/g, '/'));
return (/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/).test((s || '').replace(/\s+/g, ' ').replace(/[\-.,]/g, '/'));
},
format: function(s, table, cell, cellIndex) {
if (s) {

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*! Parser: Extract out date - updated 10/26/2014 (v2.18.0) */
/*jshint jquery:true */
;(function($){
"use strict";
'use strict';
var regex = {
usLong : /[A-Z]{3,10}\.?\s+\d{1,2},?\s+(?:\d{4})(?:\s+\d{1,2}:\d{2}(?::\d{2})?(?:\s+[AP]M)?)?/i,
@ -15,10 +15,10 @@
};
/*! extract US Long Date *//* (ignore any other text)
* e.g. "Sue's Birthday! Jun 26, 2004 7:22 AM (8# 2oz)"
* e.g. 'Sue's Birthday! Jun 26, 2004 7:22 AM (8# 2oz)'
* demo: http://jsfiddle.net/Mottie/abkNM/4165/ */
$.tablesorter.addParser({
id: "extractUSLongDate",
id: 'extractUSLongDate',
is: function () {
// don't auto detect this parser
return false;
@ -32,67 +32,67 @@
}
return s;
},
type: "numeric"
type: 'numeric'
});
/*! extract MMDDYYYY *//* (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/4166/ */
$.tablesorter.addParser({
id: "extractMMDDYYYY",
id: 'extractMMDDYYYY',
is: function () {
// don't auto detect this parser
return false;
},
format: function (s) {
var date,
str = s ? s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(regex.mdy) : s;
str = s ? s.replace(/\s+/g, ' ').replace(/[\-.,]/g, '/').match(regex.mdy) : s;
if (str) {
date = new Date( str[0] );
return date instanceof Date && isFinite(date) ? date.getTime() : s;
}
return s;
},
type: "numeric"
type: 'numeric'
});
/*! extract DDMMYYYY *//* (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/4167/ */
$.tablesorter.addParser({
id: "extractDDMMYYYY",
id: 'extractDDMMYYYY',
is: function () {
// don't auto detect this parser
return false;
},
format: function (s) {
var date,
str = s ? s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(regex.dmy) : s;
str = s ? s.replace(/\s+/g, ' ').replace(/[\-.,]/g, '/').match(regex.dmy) : s;
if (str) {
date = new Date( str[0].replace(regex.dmyreplace, "$2/$1/$3") );
date = new Date( str[0].replace(regex.dmyreplace, '$2/$1/$3') );
return date instanceof Date && isFinite(date) ? date.getTime() : s;
}
return s;
},
type: "numeric"
type: 'numeric'
});
/*! extract YYYYMMDD *//* (ignore any other text)
* demo: http://jsfiddle.net/Mottie/abkNM/4168/ */
$.tablesorter.addParser({
id: "extractYYYYMMDD",
id: 'extractYYYYMMDD',
is: function () {
// don't auto detect this parser
return false;
},
format: function (s) {
var date,
str = s ? s.replace(/\s+/g," ").replace(/[\-.,]/g, "/").match(regex.ymd) : s;
str = s ? s.replace(/\s+/g, ' ').replace(/[\-.,]/g, '/').match(regex.ymd) : s;
if (str) {
date = new Date( str[0].replace(regex.ymdreplace, "$2/$3/$1") );
date = new Date( str[0].replace(regex.ymdreplace, '$2/$3/$1') );
return date instanceof Date && isFinite(date) ? date.getTime() : s;
}
return s;
},
type: "numeric"
type: 'numeric'
});
})(jQuery);

View File

@ -6,7 +6,7 @@
*/
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var iso8601date = /^([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/;

View File

@ -2,7 +2,7 @@
/* Demo: http://jsfiddle.net/Mottie/abkNM/4169/ */
/*jshint jquery:true */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter;
ts.dates = $.extend({}, ts.dates, {
@ -12,7 +12,7 @@
ts.dates.monthLower = ts.dates.monthCased.join(',').toLocaleLowerCase().split(',');
ts.addParser({
id: "month",
id: 'month',
is: function(){
return false;
},
@ -20,7 +20,7 @@
if (s) {
var j = -1, c = table.config,
n = c.ignoreCase ? s.toLocaleLowerCase() : s;
$.each(ts.dates[ 'month' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
$.each(ts.dates[ 'month' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i, v){
if (j < 0 && n.match(v)) {
j = i;
return false;
@ -32,7 +32,7 @@
}
return s;
},
type: "numeric"
type: 'numeric'
});
})(jQuery);

View File

@ -2,7 +2,7 @@
/* Include the 'widget-filter-type-insideRange.js' to filter ranges */
/*jshint jquery:true */
;(function($){
'use strict';
'use strict';
var regex = {
mdy : /(\d{1,2}[-\s]\d{1,2}[-\s]\d{4}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/gi,

View File

@ -2,7 +2,7 @@
/* Demo: http://mottie.github.io/tablesorter/docs/example-parsers-dates.html */
/*jshint jquery:true */
;(function($){
"use strict";
'use strict';
// Make the date be within +/- range of the 2 digit year
// so if the current year is 2020, and the 2 digit year is 80 (2080 - 2020 > 50), it becomes 1980
@ -23,7 +23,7 @@
var y, rng,
n = s
// replace separators
.replace(/\s+/g," ").replace(/[-.,]/g, "/")
.replace(/\s+/g, ' ').replace(/[-.,]/g, '/')
// reformat xx/xx/xx to mm/dd/19yy;
.replace(regex, format),
d = new Date(n);
@ -31,7 +31,7 @@
y = d.getFullYear();
rng = table && table.config.dateRange || range;
// if date > 50 years old (set range), add 100 years
// this will work when people start using "50" and mean "2050"
// this will work when people start using '50' and mean '2050'
while (now - y > rng) {
y += 100;
}
@ -42,39 +42,39 @@
};
$.tablesorter.addParser({
id: "ddmmyy",
id: 'ddmmyy',
is: function() {
return false;
},
format: function(s, table) {
// reformat dd/mm/yy to mm/dd/19yy;
return ts.formatDate(s, ts.dates.regxxxxyy, "$2/$1/19$3", table);
return ts.formatDate(s, ts.dates.regxxxxyy, '$2/$1/19$3', table);
},
type: "numeric"
type: 'numeric'
});
$.tablesorter.addParser({
id: "mmddyy",
id: 'mmddyy',
is: function() {
return false;
},
format: function(s, table) {
// reformat mm/dd/yy to mm/dd/19yy
return ts.formatDate(s, ts.dates.regxxxxyy, "$1/$2/19$3", table);
return ts.formatDate(s, ts.dates.regxxxxyy, '$1/$2/19$3', table);
},
type: "numeric"
type: 'numeric'
});
$.tablesorter.addParser({
id: "yymmdd",
id: 'yymmdd',
is: function() {
return false;
},
format: function(s, table) {
// reformat yy/mm/dd to mm/dd/19yy
return ts.formatDate(s, ts.dates.regyyxxxx, "$2/$3/19$1", table);
return ts.formatDate(s, ts.dates.regyyxxxx, '$2/$3/19$1', table);
},
type: "numeric"
type: 'numeric'
});
})(jQuery);

View File

@ -2,7 +2,7 @@
/* Demo: http://jsfiddle.net/Mottie/abkNM/4169/ */
/*jshint jquery:true */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter;
ts.dates = $.extend({}, ts.dates, {
@ -12,7 +12,7 @@
ts.dates.weekdayLower = ts.dates.weekdayCased.join(',').toLocaleLowerCase().split(',');
ts.addParser({
id: "weekday",
id: 'weekday',
is: function(){
return false;
},
@ -20,7 +20,7 @@
if (s) {
var j = -1, c = table.config;
s = c.ignoreCase ? s.toLocaleLowerCase() : s;
$.each(ts.dates[ 'weekday' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){
$.each(ts.dates[ 'weekday' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i, v){
if (j < 0 && s.match(v)) {
j = i;
return false;
@ -32,7 +32,7 @@
}
return s;
},
type: "numeric"
type: 'numeric'
});
})(jQuery);

View File

@ -2,7 +2,7 @@
/* Extract dates using popular natural language date parsers */
/*jshint jquery:true */
;(function($){
'use strict';
'use strict';
/*! Sugar (http://sugarjs.com/dates#comparing_dates) */
/* demo: http://jsfiddle.net/Mottie/abkNM/4163/ */

View File

@ -1,7 +1,7 @@
/*! Parser: duration & countdown - updated 2/7/2015 (v2.19.0) */
/*jshint jquery:true, unused:false */
;(function($){
'use strict';
'use strict';
// If any number > 9999, then set table.config.durationLength = 5
// The below regex matches this duration example: 1y 23d 12h 44m 9s

View File

@ -5,21 +5,21 @@
*/
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter;
ts.symbolRegex = /[\u215b\u215c\u215d\u215e\u00bc\u00bd\u00be]/g;
ts.processFractions = function(n, table) {
if (n) {
var t, p = 0;
n = $.trim(n.replace(/\"/,''));
// look for a space in the first part of the number: "10 3/4" and save the "10"
n = $.trim(n.replace(/\"/, ''));
// look for a space in the first part of the number: '10 3/4' and save the '10'
if (/\s/.test(n)) {
p = ts.formatFloat(n.split(' ')[0], table);
// remove stuff to the left of the space
n = $.trim(n.substring(n.indexOf(' '), n.length));
}
// look for a "/" to calculate fractions
// look for a '/' to calculate fractions
if (/\//g.test(n)) {
t = n.split('/');
// turn 3/4 into .75; make sure we don't divide by zero
@ -52,10 +52,10 @@
if (s === '') { return ''; }
// look for feet symbol = '
// very generic test to catch 1.1', 1 1/2' and 1½'
var d = (/^\s*\S*(\s+\S+)?\s*\'/.test(s)) ? s.split("'") : [0,s],
var d = (/^\s*\S*(\s+\S+)?\s*\'/.test(s)) ? s.split(/\'/) : [ 0, s ],
f = ts.processFractions(d[0], table), // feet
i = ts.processFractions(d[1], table); // inches
return (/[\'\"]/).test(s) ? parseFloat(f) + (parseFloat(i)/12 || 0) : parseFloat(f) + parseFloat(i);
return (/[\'\"]/).test(s) ? parseFloat(f) + (parseFloat(i) / 12 || 0) : parseFloat(f) + parseFloat(i);
},
type: 'numeric'
});

View File

@ -4,33 +4,33 @@
*/
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
// basic list from http://en.wikipedia.org/wiki/List_of_file_formats
// To add a custom equivalent, define:
// $.tablesorter.fileTypes.equivalents['xx'] = "A|B|C";
// $.tablesorter.fileTypes.equivalents['xx'] = 'A|B|C';
$.tablesorter.fileTypes = {
// divides filetype extensions in the equivalent list below
separator : '|',
equivalents : {
"3D Image" : "3dm|3ds|dwg|max|obj",
"Audio" : "aif|aac|ape|flac|la|m4a|mid|midi|mp2|mp3|ogg|ra|raw|rm|wav|wma",
"Compressed" : "7z|bin|cab|cbr|gz|gzip|iso|lha|lz|rar|tar|tgz|zip|zipx|zoo",
"Database" : "csv|dat|db|dbf|json|ldb|mdb|myd|pdb|sql|tsv|wdb|wmdb|xlr|xls|xlsx|xml",
"Development" : "asm|c|class|cls|cpp|cc|cs|cxx|cbp|cs|dba|fla|h|java|lua|pl|py|pyc|pyo|sh|sln|r|rb|vb",
"Document" : "doc|docx|odt|ott|pages|pdf|rtf|tex|wpd|wps|wrd|wri",
"Executable" : "apk|app|com|exe|gadget|lnk|msi",
"Fonts" : "eot|fnt|fon|otf|ttf|woff",
"Icons" : "ani|cur|icns|ico",
"Images" : "bmp|gif|jpg|jpeg|jpe|jp2|pic|png|psd|tga|tif|tiff|wmf|webp",
"Presentation" : "pps|ppt",
"Published" : "chp|epub|lit|pub|ppp|fm|mobi",
"Script" : "as|bat|cgi|cmd|jar|js|lua|scpt|scptd|sh|vbs|vb|wsf",
"Styles" : "css|less|sass",
"Text" : "info|log|md|markdown|nfo|tex|text|txt",
"Vectors" : "awg|ai|eps|cdr|ps|svg",
"Video" : "asf|avi|flv|m4v|mkv|mov|mp4|mpe|mpeg|mpg|ogg|rm|rv|swf|vob|wmv",
"Web" : "asp|aspx|cer|cfm|htm|html|php|url|xhtml"
'3D Image' : '3dm|3ds|dwg|max|obj',
'Audio' : 'aif|aac|ape|flac|la|m4a|mid|midi|mp2|mp3|ogg|ra|raw|rm|wav|wma',
'Compressed' : '7z|bin|cab|cbr|gz|gzip|iso|lha|lz|rar|tar|tgz|zip|zipx|zoo',
'Database' : 'csv|dat|db|dbf|json|ldb|mdb|myd|pdb|sql|tsv|wdb|wmdb|xlr|xls|xlsx|xml',
'Development' : 'asm|c|class|cls|cpp|cc|cs|cxx|cbp|cs|dba|fla|h|java|lua|pl|py|pyc|pyo|sh|sln|r|rb|vb',
'Document' : 'doc|docx|odt|ott|pages|pdf|rtf|tex|wpd|wps|wrd|wri',
'Executable' : 'apk|app|com|exe|gadget|lnk|msi',
'Fonts' : 'eot|fnt|fon|otf|ttf|woff',
'Icons' : 'ani|cur|icns|ico',
'Images' : 'bmp|gif|jpg|jpeg|jpe|jp2|pic|png|psd|tga|tif|tiff|wmf|webp',
'Presentation' : 'pps|ppt',
'Published' : 'chp|epub|lit|pub|ppp|fm|mobi',
'Script' : 'as|bat|cgi|cmd|jar|js|lua|scpt|scptd|sh|vbs|vb|wsf',
'Styles' : 'css|less|sass',
'Text' : 'info|log|md|markdown|nfo|tex|text|txt',
'Vectors' : 'awg|ai|eps|cdr|ps|svg',
'Video' : 'asf|avi|flv|m4v|mkv|mov|mp4|mpe|mpeg|mpg|ogg|rm|rv|swf|vob|wmv',
'Web' : 'asp|aspx|cer|cfm|htm|html|php|url|xhtml'
}
};
@ -48,9 +48,9 @@
m = $.tablesorter.fileTypes.matching,
types = $.tablesorter.fileTypes.equivalents;
if (!m) {
// make a string to "quick" match the existing equivalents
// make a string to 'quick' match the existing equivalents
t = [];
$.each(types, function(i,v){
$.each(types, function(i, v){
t.push(v);
});
m = $.tablesorter.fileTypes.matching = sep + t.join(sep) + sep;

View File

@ -3,7 +3,7 @@
Globalize.locale( 'xx' ) prior to initializing tablesorter! */
/*jshint jquery:true */
;( function( $ ) {
'use strict';
'use strict';
/*! jQuery Globalize date parser (https://github.com/jquery/globalize#date-module) */
/* demo: http://jsfiddle.net/Mottie/0j18Lw8r/ */

View File

@ -1,28 +1,28 @@
/*! Parser: ignoreArticles - updated 9/15/2014 (v2.17.8) *//*
* This parser will remove "The", "A" and "An" from the beginning of a book
* This parser will remove 'The', 'A' and 'An' from the beginning of a book
* or movie title, so it sorts by the second word or number
* Demo: http://jsfiddle.net/Mottie/abkNM/5/
*/
/*jshint browser: true, jquery:true, unused:false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter;
var ts = $.tablesorter;
// basic list from http://en.wikipedia.org/wiki/Article_%28grammar%29
ts.ignoreArticles = {
"en" : "the, a, an",
"de" : "der, die, das, des, dem, den, ein, eine, einer, eines, einem, einen",
"nl" : "de, het, de, een",
"es" : "el, la, lo, los, las, un, una, unos, unas",
"pt" : "o, a, os, as, um, uma, uns, umas",
"fr" : "le, la, l'_, les, un, une, des",
"it" : "il, lo, la, l'_, i, gli, le, un', uno, una, un",
"hu" : "a, az, egy"
'en' : 'the, a, an',
'de' : 'der, die, das, des, dem, den, ein, eine, einer, eines, einem, einen',
'nl' : 'de, het, de, een',
'es' : 'el, la, lo, los, las, un, una, unos, unas',
'pt' : 'o, a, os, as, um, uma, uns, umas',
'fr' : 'le, la, l\'_, les, un, une, des',
'it' : 'il, lo, la, l\'_, i, gli, le, un\', uno, una, un',
'hu' : 'a, az, egy'
};
// To add a custom parser, define:
// $.tablesorter.ignoreArticles['xx'] = "A, B, C";
// $.tablesorter.ignoreArticles['xx'] = 'A, B, C';
// and then set the language id 'xx' in the headers option
// ignoreArticles : 'xx'
@ -40,11 +40,11 @@ var ts = $.tablesorter;
if (!c.headers) { c.headers = {}; }
if (!c.headers[cellIndex]) { c.headers[cellIndex] = {}; }
lang = ts.getData( c.$headers.eq(cellIndex), ts.getColumnData( table, c.headers, cellIndex ), 'ignoreArticles' );
art = (ts.ignoreArticles[lang] || "the, a, an" ) + "";
c.headers[cellIndex].ignoreArticlesRegex = new RegExp('^(' + $.trim( art.split(/\s*\,\s*/).join('\\s|') + "\\s" ).replace("_\\s","") + ')', 'i');
art = (ts.ignoreArticles[lang] || 'the, a, an' ) + '';
c.headers[cellIndex].ignoreArticlesRegex = new RegExp('^(' + $.trim( art.split(/\s*\,\s*/).join('\\s|') + '\\s' ).replace('_\\s', '') + ')', 'i');
// exception regex stored in c.headers[cellIndex].ignoreArticlesRegex2
ignore = ts.getData( c.$headers.eq(cellIndex), ts.getColumnData( table, c.headers, cellIndex ), 'ignoreArticlesExcept' );
c.headers[cellIndex].ignoreArticlesRegex2 = ignore !== '' ? new RegExp('^(' + ignore.replace(/\s/g, "\\s") + ')', 'i') : '';
c.headers[cellIndex].ignoreArticlesRegex2 = ignore !== '' ? new RegExp('^(' + ignore.replace(/\s/g, '\\s') + ')', 'i') : '';
}
art = c.headers[cellIndex].ignoreArticlesRegex;
if (art.test(str)) {

View File

@ -2,10 +2,10 @@
/* alt attribute parser for jQuery 1.7+ & tablesorter 2.7.11+ */
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
'use strict';
$.tablesorter.addParser({
id: "image",
id: 'image',
is: function(){
return false;
},
@ -13,7 +13,7 @@
return $(cell).find('img').attr(table.config.imgAttr || 'alt') || s;
},
parsed : true, // filter widget flag
type: "text"
type: 'text'
});
})(jQuery);

View File

@ -4,7 +4,7 @@
*/
/*jshint browser: true, jquery:true, unused:false */
;( function( $ ) {
'use strict';
'use strict';
var updateServer = function( event, $table, $input ) {
// do something here to update your server, if needed

View File

@ -6,7 +6,7 @@
*/
/*jshint jquery:true */
;( function( $ ) {
'use strict';
'use strict';
var prefixes = {
// 'prefix' : [ base 10, base 2 ]
@ -23,7 +23,7 @@
'h|hecto' : [ 1e2, 1e2 ],
'da|deka' : [ 1e1, 1e1 ],
'd|deci' : [ 1e-1, 1e-1 ],
'c|centi' : [ 1e-2, 1e-2],
'c|centi' : [ 1e-2, 1e-2 ],
'm|milli' : [ 1e-3, 1e-3 ],
'µ|micro' : [ 1e-6, 1e-6 ],
'n|nano' : [ 1e-9, 1e-9 ],

View File

@ -3,7 +3,7 @@
*/
/*jshint jquery:true */
;(function($){
"use strict";
'use strict';
// Change language of the named numbers as needed
var named = {
@ -99,7 +99,7 @@
};
$.tablesorter.addParser({
id: "namedNumbers",
id: 'namedNumbers',
is: function () {
return false;
},
@ -116,7 +116,7 @@
// make sure to let zero get parsed, so check hasOwnProperty
return result || named.numbers.hasOwnProperty( str ) ? result : $.tablesorter.formatFloat( str || '', table );
},
type: "numeric"
type: 'numeric'
});
})( jQuery );

View File

@ -69,7 +69,7 @@
// it's fastest & easiest for tablesorter to sort decimal values (vs hex)
groups[i] = hex ? ('0000' + groups[i]).slice(-4) :
('00000' + (parseInt(groups[i], 16) || 0)).slice(-5);
expandedAddress += ( i != validGroupCount-1) ? groups[i] + ':' : groups[i];
expandedAddress += ( i != validGroupCount - 1) ? groups[i] + ':' : groups[i];
}
return hex ? expandedAddress : expandedAddress.replace(/:/g, '');
},

View File

@ -5,7 +5,7 @@
*/
/*jshint jquery:true, unused:false */
;(function($){
"use strict";
'use strict';
// allow lower case roman numerals, since lists use i, ii, iii, etc.
var validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/i,
@ -34,7 +34,7 @@
return num;
},
type: "numeric"
type: 'numeric'
});
$.tablesorter.addParser({
@ -75,7 +75,7 @@
return num ? s.replace(orig, num) : s;
},
type: "text"
type: 'text'
});
$.tablesorter.addParser({
@ -111,7 +111,7 @@
return num ? num : s;
},
type: "numeric"
type: 'numeric'
});
})(jQuery);

View File

@ -5,142 +5,143 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
'use strict';
var ts = $.tablesorter;
ts.alignChar = {
ts.alignChar = {
init : function(table, c, wo) {
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
var $this = $(this),
vars = {
column : this.column,
align : $this.attr(wo.alignChar_charAttrib),
alignIndex : parseInt( $this.attr(wo.alignChar_indexAttrib) || 0, 10),
adjust : parseFloat($this.attr(wo.alignChar_adjustAttrib)) || 0
};
vars.regex = new RegExp('\\' + vars.align, 'g');
if (typeof vars.align !== 'undefined') {
wo.alignChar_savedVars[this.column] = vars;
ts.alignChar.setup(table, c, wo, vars);
}
});
},
init : function(table, c, wo) {
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
var $this = $(this),
vars = {
column : this.column,
align : $this.attr(wo.alignChar_charAttrib),
alignIndex : parseInt( $this.attr(wo.alignChar_indexAttrib) || 0, 10),
adjust : parseFloat($this.attr(wo.alignChar_adjustAttrib)) || 0
};
vars.regex = new RegExp('\\' + vars.align, 'g');
if (typeof vars.align !== 'undefined') {
wo.alignChar_savedVars[this.column] = vars;
ts.alignChar.setup(table, c, wo, vars);
}
});
},
setup: function(table, c, wo, v){
// do nothing for empty tables
if ($.isEmptyObject(c.cache)) { return; }
var tbodyIndex, rowIndex, start, end, last, index, rows, val, count,
len, wLeft, wRight, alignChar, $row,
left = [],
right = [];
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
// set up to work with modified cache v2.16.0+
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
val = $row.find('td').eq(v.column).text().replace(/[ ]/g, "\u00a0");
// count how many "align" characters are in the string
count = (val.match( v.regex ) || []).length;
// set alignment @ alignIndex (one-based index)
if (count > 0 && v.alignIndex > 0) {
end = Math.min(v.alignIndex, count);
start = 0;
index = 0;
last = 0;
// find index of nth align character based on alignIndex (data-align-index)
while (start++ < end) {
last = val.indexOf(v.align, last + 1);
index = last < 0 ? index : last;
setup: function(table, c, wo, v){
// do nothing for empty tables
if ($.isEmptyObject(c.cache)) { return; }
var tbodyIndex, rowIndex, start, end, last, index, rows, val, count,
len, wLeft, wRight, alignChar, $row,
left = [],
right = [];
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
// set up to work with modified cache v2.16.0+
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
val = $row.find('td').eq(v.column).text().replace(/[ ]/g, '\u00a0');
// count how many 'align' characters are in the string
count = (val.match( v.regex ) || []).length;
// set alignment @ alignIndex (one-based index)
if (count > 0 && v.alignIndex > 0) {
end = Math.min(v.alignIndex, count);
start = 0;
index = 0;
last = 0;
// find index of nth align character based on alignIndex (data-align-index)
while (start++ < end) {
last = val.indexOf(v.align, last + 1);
index = last < 0 ? index : last;
}
} else {
index = val.indexOf(v.align);
}
if ( index >= 0 ) {
left.push( val.substring(0, index) || '' );
right.push( val.substring(index, val.length) || '' );
} else {
// no align character found!
// put val in right or left based on the align index
left.push( (count >= 1 && v.alignIndex >= count) ? '' : val || '' );
right.push( (count >= 1 && v.alignIndex >= count) ? val || '' : '' );
}
} else {
index = val.indexOf(v.align);
}
if ( index >= 0 ) {
left.push( val.substring(0, index) || '' );
right.push( val.substring(index, val.length) || '' );
} else {
// no align character found!
// put val in right or left based on the align index
left.push( (count >= 1 && v.alignIndex >= count) ? '' : val || '' );
right.push( (count >= 1 && v.alignIndex >= count) ? val || '' : '' );
}
// find widest segments
wLeft = ($.extend([], left)).sort(function(a, b){ return b.length - a.length; })[0];
wRight = ($.extend([], right)).sort(function(a, b){ return b.length - a.length; })[0];
// calculate percentage widths
v.width = v.width || ( Math.floor(wLeft.length / (wLeft.length + wRight.length) * 100) + v.adjust );
wLeft = 'min-width:' + v.width + '%';
wRight = 'min-width:' + (100 - v.width) + '%';
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
alignChar = $(wo.alignChar_wrap).length ? $(wo.alignChar_wrap).html(v.align)[0].outerHTML : v.align;
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
last = right[rowIndex].slice(v.align.length);
$row.find('td').eq(v.column).html(
'<span class="ts-align-wrap"><span class="ts-align-left" style="' + wLeft + '">' + left[rowIndex] + '</span>' +
'<span class="ts-align-right" style="' + wRight + '">' + ( last.length ? alignChar + last : '' ) + '</span></span>'
);
}
}
wo.alignChar_initialized = true;
},
remove: function(table, c, column){
if ($.isEmptyObject(c.cache)) { return; }
var tbodyIndex, rowIndex, len, rows, $row, $cell;
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
$cell = $row.find('td').eq(column);
$cell.html( $cell.text().replace(/\s/g, ' ') );
}
}
}
};
// find widest segments
wLeft = ($.extend([], left)).sort(function(a,b){ return b.length - a.length; })[0];
wRight = ($.extend([], right)).sort(function(a,b){ return b.length - a.length; })[0];
// calculate percentage widths
v.width = v.width || ( Math.floor(wLeft.length / (wLeft.length + wRight.length) * 100) + v.adjust );
wLeft = 'min-width:' + v.width + '%';
wRight = 'min-width:' + (100 - v.width) + '%';
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
alignChar = $(wo.alignChar_wrap).length ? $(wo.alignChar_wrap).html(v.align)[0].outerHTML : v.align;
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
last = right[rowIndex].slice(v.align.length);
$row.find('td').eq(v.column).html(
'<span class="ts-align-wrap"><span class="ts-align-left" style="' + wLeft + '">' + left[rowIndex] + '</span>' +
'<span class="ts-align-right" style="' + wRight + '">' + ( last.length ? alignChar + last : '' ) + '</span></span>'
);
ts.addWidget({
id: 'alignChar',
priority: 100,
options: {
alignChar_wrap : '',
alignChar_charAttrib : 'data-align-char',
alignChar_indexAttrib : 'data-align-index',
alignChar_adjustAttrib : 'data-align-adjust' // percentage width adjustments
},
init: function(table, thisWidget, c, wo){
wo.alignChar_initialized = false;
wo.alignChar_savedVars = [];
ts.alignChar.init(table, c, wo);
c.$table.on('pagerEnd refreshAlign', function(){
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
ts.alignChar.remove(table, c, this.column);
});
ts.alignChar.init(table, c, wo);
});
},
format : function(table, c, wo){
// reinitialize in case table is empty when first initialized
if (!wo.alignChar_initialized) {
c.$table.trigger('refreshAlign');
}
}
wo.alignChar_initialized = true;
},
remove: function(table, c, column){
if ($.isEmptyObject(c.cache)) { return; }
var tbodyIndex, rowIndex, len, rows, $row, $cell;
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++){
rows = c.cache[tbodyIndex];
len = rows.normalized.length;
for (rowIndex = 0; rowIndex < len; rowIndex++) {
$row = rows.row ? rows.row[rowIndex] : rows.normalized[rowIndex][c.columns].$row;
$cell = $row.find('td').eq(column);
$cell.html( $cell.text().replace(/\s/g, ' ') );
}
}
}
};
ts.addWidget({
id: 'alignChar',
priority: 100,
options: {
alignChar_wrap : '',
alignChar_charAttrib : 'data-align-char',
alignChar_indexAttrib : 'data-align-index',
alignChar_adjustAttrib : 'data-align-adjust' // percentage width adjustments
},
init: function(table, thisWidget, c, wo){
wo.alignChar_initialized = false;
wo.alignChar_savedVars = [];
ts.alignChar.init(table, c, wo);
c.$table.on('pagerEnd refreshAlign', function(){
},
remove : function(table, c, wo, refreshing){
if (refreshing) { return; }
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
ts.alignChar.remove(table, c, this.column);
});
ts.alignChar.init(table, c, wo);
});
},
format : function(table, c, wo){
// reinitialize in case table is empty when first initialized
if (!wo.alignChar_initialized) {
c.$table.trigger('refreshAlign');
wo.alignChar_initialized = false;
}
},
remove : function(table, c, wo, refreshing){
if (refreshing) { return; }
c.$headers.filter('[' + wo.alignChar_charAttrib + ']').each(function(){
ts.alignChar.remove(table, c, this.column);
});
wo.alignChar_initialized = false;
}
});
});
})(jQuery);

View File

@ -5,8 +5,8 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter = $.tablesorter || {},
'use strict';
var ts = $.tablesorter = $.tablesorter || {},
// build a table from data (requires existing <table> tag)
// data.header contains an array of header titles
@ -40,7 +40,7 @@ var ts = $.tablesorter = $.tablesorter || {},
// valid JSON!
return bt.object( table, d, wo );
}
} catch(ignore) {}
} catch (ignore) {}
// fall through in case it's a csv string
}
// Array
@ -105,7 +105,7 @@ var ts = $.tablesorter = $.tablesorter || {},
// *** CSV only options ***
build_csvStartLine : 0, // line within the csv to start adding to table
build_csvSeparator : ",", // csv separator
build_csvSeparator : ',', // csv separator
// *** build object options ***
build_objectRowKey : 'rows', // object key containing table rows
@ -225,7 +225,7 @@ var ts = $.tablesorter = $.tablesorter || {},
var c, h,
csv = wo.build_type === 'csv' || typeof data === 'string',
$t = $(table),
lines = csv ? data.replace('\r','').split('\n') : data,
lines = csv ? data.replace('\r', '').split('\n') : data,
len = lines.length,
printedLines = 0,
infooter = false,
@ -276,13 +276,13 @@ var ts = $.tablesorter = $.tablesorter || {},
// CSV Parser by Brian Huisman (http://www.greywyvern.com/?post=258)
bt.splitCSV = function(str, sep) {
var x, tl,
thisCSV = $.trim(str).split(sep = sep || ",");
thisCSV = $.trim(str).split(sep = sep || ',');
for ( x = thisCSV.length - 1; x >= 0; x-- ) {
if ( thisCSV[x].replace(/\"\s+$/, '"').charAt(thisCSV[x].length - 1) === '"' ) {
if ( (tl = thisCSV[x].replace(/^\s+\"/, '"')).length > 1 && tl.charAt(0) === '"' ) {
thisCSV[x] = thisCSV[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"');
} else if (x) {
thisCSV.splice(x - 1, 2, [thisCSV[x - 1], thisCSV[x]].join(sep));
thisCSV.splice(x - 1, 2, [ thisCSV[x - 1], thisCSV[x] ].join(sep));
} else {
thisCSV = thisCSV.shift().split(sep).concat(thisCSV);
}
@ -304,7 +304,7 @@ var ts = $.tablesorter = $.tablesorter || {},
bt.buildComplete(table, wo);
};
/* ==== Object example ====
/* ==== Object example ====
data : {
headers : [
[
@ -345,9 +345,9 @@ var ts = $.tablesorter = $.tablesorter || {},
}
]
}
*/
*/
bt.object = function(table, data, wo) {
// "rows"
// 'rows'
var j, l, t, $c, $t, $tb, $tr,
c = table.config,
kh = wo.build_objectHeaderKey,

View File

@ -32,7 +32,7 @@
.off(wo.chart_event)
.on(wo.chart_event, function() {
if (this.hasInitialized) {
// refresh "c" variable in case options are updated dynamically
// refresh 'c' variable in case options are updated dynamically
var c = this.config;
chart.getCols(c, c.widgetOptions);
chart.getData(c, c.widgetOptions);
@ -258,7 +258,7 @@
// Set the label column
chart_labelCol: 0,
// data sort, should always be first row, might want [[0,1]]
chart_sort: [[0,0]],
chart_sort: [ [ 0, 0 ] ],
// event to trigger get updated data
chart_event: 'chartData'
},

View File

@ -5,362 +5,362 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter,
namespace = '.tscolsel',
tsColSel = ts.columnSelector = {
var ts = $.tablesorter,
namespace = '.tscolsel',
tsColSel = ts.columnSelector = {
queryAll : '@media only all { [columns] { display: none; } } ',
queryBreak : '@media all and (min-width: [size]) { [columns] { display: table-cell; } } ',
queryAll : '@media only all { [columns] { display: none; } } ',
queryBreak : '@media all and (min-width: [size]) { [columns] { display: table-cell; } } ',
init: function(table, c, wo) {
var $t, colSel;
init: function(table, c, wo) {
var $t, colSel;
// abort if no input is contained within the layout
$t = $(wo.columnSelector_layout);
if (!$t.find('input').add( $t.filter('input') ).length) {
if (c.debug) {
ts.log('ColumnSelector: >> ERROR: Column Selector aborting, no input found in the layout! ***');
// abort if no input is contained within the layout
$t = $(wo.columnSelector_layout);
if (!$t.find('input').add( $t.filter('input') ).length) {
if (c.debug) {
ts.log('ColumnSelector: >> ERROR: Column Selector aborting, no input found in the layout! ***');
}
return;
}
return;
}
// unique table class name
c.$table.addClass( c.namespace.slice(1) + 'columnselector' );
// unique table class name
c.$table.addClass( c.namespace.slice(1) + 'columnselector' );
// build column selector/state array
colSel = c.selector = { $container : $(wo.columnSelector_container || '<div>') };
colSel.$style = $('<style></style>').prop('disabled', true).appendTo('head');
colSel.$breakpoints = $('<style></style>').prop('disabled', true).appendTo('head');
// build column selector/state array
colSel = c.selector = { $container : $(wo.columnSelector_container || '<div>') };
colSel.$style = $('<style></style>').prop('disabled', true).appendTo('head');
colSel.$breakpoints = $('<style></style>').prop('disabled', true).appendTo('head');
colSel.isInitializing = true;
tsColSel.setupSelector(table, c, wo);
colSel.isInitializing = true;
tsColSel.setupSelector(table, c, wo);
if (wo.columnSelector_mediaquery) {
tsColSel.setupBreakpoints(c, wo);
}
if (wo.columnSelector_mediaquery) {
tsColSel.setupBreakpoints(c, wo);
}
colSel.isInitializing = false;
if (colSel.$container.length) {
tsColSel.updateCols(c, wo);
} else if (c.debug) {
ts.log('ColumnSelector: >> container not found');
}
colSel.isInitializing = false;
if (colSel.$container.length) {
tsColSel.updateCols(c, wo);
} else if (c.debug) {
ts.log('ColumnSelector: >> container not found');
}
c.$table
.off('refreshColumnSelector' + namespace)
.on('refreshColumnSelector' + namespace, function(e, opt){
// make sure we're using current config settings
var i,
isArry = $.isArray(opt),
c = this.config,
wo = c.widgetOptions;
// see #798
if (opt && c.selector.$container.length) {
if (isArry) {
// make sure array contains numbers
$.each(opt, function(i,v){
opt[i] = parseInt(v, 10);
});
for (i = 0; i < c.columns; i++) {
c.selector.$container
.find('input[data-column=' + i + ']')
.prop('checked', $.inArray( i, opt ) >= 0 );
c.$table
.off('refreshColumnSelector' + namespace)
.on('refreshColumnSelector' + namespace, function(e, opt){
// make sure we're using current config settings
var i,
isArry = $.isArray(opt),
c = this.config,
wo = c.widgetOptions;
// see #798
if (opt && c.selector.$container.length) {
if (isArry) {
// make sure array contains numbers
$.each(opt, function(i, v){
opt[i] = parseInt(v, 10);
});
for (i = 0; i < c.columns; i++) {
c.selector.$container
.find('input[data-column=' + i + ']')
.prop('checked', $.inArray( i, opt ) >= 0 );
}
}
// if passing an array, set auto to false to allow manual column selection & update columns
tsColSel.updateAuto( c, wo, colSel.$container.find('input[data-column="auto"]').prop('checked', !isArry) );
} else {
tsColSel.updateBreakpoints(c, wo);
tsColSel.updateCols(c, wo);
}
// if passing an array, set auto to false to allow manual column selection & update columns
tsColSel.updateAuto( c, wo, colSel.$container.find('input[data-column="auto"]').prop('checked', !isArry) );
} else {
tsColSel.updateBreakpoints(c, wo);
tsColSel.updateCols(c, wo);
});
},
setupSelector: function(table, c, wo) {
var name,
colSel = c.selector,
$container = colSel.$container,
useStorage = wo.columnSelector_saveColumns && ts.storage,
// get stored column states
saved = useStorage ? ts.storage( table, 'tablesorter-columnSelector' ) : [],
state = useStorage ? ts.storage( table, 'tablesorter-columnSelector-auto') : {};
// initial states
colSel.auto = $.isEmptyObject(state) || $.type(state.auto) !== 'boolean' ? wo.columnSelector_mediaqueryState : state.auto;
colSel.states = [];
colSel.$column = [];
colSel.$wrapper = [];
colSel.$checkbox = [];
// populate the selector container
c.$table.children('thead').find('tr:first th', table).each(function() {
var $this = $(this),
// if no data-priority is assigned, default to 1, but don't remove it from the selector list
priority = $this.attr(wo.columnSelector_priority) || 1,
colId = $this.attr('data-column'),
state = ts.getData(this, c.headers[colId], 'columnSelector');
// if this column not hidable at all
// include getData check (includes 'columnSelector-false' class, data attribute, etc)
if ( isNaN(priority) && priority.length > 0 || state === 'disable' ||
( wo.columnSelector_columns[colId] && wo.columnSelector_columns[colId] === 'disable') ) {
return true; // goto next
}
// set default state; storage takes priority
colSel.states[colId] = saved && typeof saved[colId] !== 'undefined' ?
saved[colId] : typeof wo.columnSelector_columns[colId] !== 'undefined' ?
wo.columnSelector_columns[colId] : (state === 'true' || state !== 'false');
colSel.$column[colId] = $(this);
// set default col title
name = $this.attr(wo.columnSelector_name) || $this.text();
if ($container.length) {
colSel.$wrapper[colId] = $(wo.columnSelector_layout.replace(/\{name\}/g, name)).appendTo($container);
colSel.$checkbox[colId] = colSel.$wrapper[colId]
// input may not be wrapped within the layout template
.find('input').add( colSel.$wrapper[colId].filter('input') )
.attr('data-column', colId)
.toggleClass( wo.columnSelector_cssChecked, colSel.states[colId] )
.prop('checked', colSel.states[colId])
.on('change', function(){
colSel.states[colId] = this.checked;
tsColSel.updateCols(c, wo);
}).change();
}
});
},
},
setupSelector: function(table, c, wo) {
var name,
colSel = c.selector,
$container = colSel.$container,
useStorage = wo.columnSelector_saveColumns && ts.storage,
// get stored column states
saved = useStorage ? ts.storage( table, 'tablesorter-columnSelector' ) : [],
state = useStorage ? ts.storage( table, 'tablesorter-columnSelector-auto') : {};
setupBreakpoints: function(c, wo){
var colSel = c.selector;
// initial states
colSel.auto = $.isEmptyObject(state) || $.type(state.auto) !== "boolean" ? wo.columnSelector_mediaqueryState : state.auto;
colSel.states = [];
colSel.$column = [];
colSel.$wrapper = [];
colSel.$checkbox = [];
// populate the selector container
c.$table.children('thead').find('tr:first th', table).each(function() {
var $this = $(this),
// if no data-priority is assigned, default to 1, but don't remove it from the selector list
priority = $this.attr(wo.columnSelector_priority) || 1,
colId = $this.attr('data-column'),
state = ts.getData(this, c.headers[colId], 'columnSelector');
// if this column not hidable at all
// include getData check (includes "columnSelector-false" class, data attribute, etc)
if ( isNaN(priority) && priority.length > 0 || state === 'disable' ||
( wo.columnSelector_columns[colId] && wo.columnSelector_columns[colId] === 'disable') ) {
return true; // goto next
}
// set default state; storage takes priority
colSel.states[colId] = saved && typeof(saved[colId]) !== 'undefined' ?
saved[colId] : typeof(wo.columnSelector_columns[colId]) !== 'undefined' ?
wo.columnSelector_columns[colId] : (state === 'true' || state !== 'false');
colSel.$column[colId] = $(this);
// set default col title
name = $this.attr(wo.columnSelector_name) || $this.text();
if ($container.length) {
colSel.$wrapper[colId] = $(wo.columnSelector_layout.replace(/\{name\}/g, name)).appendTo($container);
colSel.$checkbox[colId] = colSel.$wrapper[colId]
// input may not be wrapped within the layout template
.find('input').add( colSel.$wrapper[colId].filter('input') )
.attr('data-column', colId)
.toggleClass( wo.columnSelector_cssChecked, colSel.states[colId] )
.prop('checked', colSel.states[colId])
.on('change', function(){
colSel.states[colId] = this.checked;
// add responsive breakpoints
if (wo.columnSelector_mediaquery) {
// used by window resize function
colSel.lastIndex = -1;
tsColSel.updateBreakpoints(c, wo);
c.$table
.off('updateAll' + namespace)
.on('updateAll' + namespace, function(){
tsColSel.updateBreakpoints(c, wo);
tsColSel.updateCols(c, wo);
}).change();
});
}
});
},
setupBreakpoints: function(c, wo){
var colSel = c.selector;
// add responsive breakpoints
if (wo.columnSelector_mediaquery) {
// used by window resize function
colSel.lastIndex = -1;
tsColSel.updateBreakpoints(c, wo);
c.$table
.off('updateAll' + namespace)
.on('updateAll' + namespace, function(){
tsColSel.updateBreakpoints(c, wo);
if (colSel.$container.length) {
// Add media queries toggle
if (wo.columnSelector_mediaquery) {
colSel.$auto = $( wo.columnSelector_layout.replace(/\{name\}/g, wo.columnSelector_mediaqueryName) ).prependTo(colSel.$container);
colSel.$auto
// needed in case the input in the layout is not wrapped
.find('input').add( colSel.$auto.filter('input') )
.attr('data-column', 'auto')
.prop('checked', colSel.auto)
.toggleClass( wo.columnSelector_cssChecked, colSel.auto )
.on('change', function(){
tsColSel.updateAuto(c, wo, $(this));
}).change();
}
// Add a bind on update to re-run col setup
c.$table.off('update' + namespace).on('update' + namespace, function() {
tsColSel.updateCols(c, wo);
});
}
}
},
if (colSel.$container.length) {
// Add media queries toggle
updateAuto: function(c, wo, $el) {
var colSel = c.selector;
colSel.auto = $el.prop('checked') || false;
$.each( colSel.$checkbox, function(i, $cb){
if ($cb) {
$cb[0].disabled = colSel.auto;
colSel.$wrapper[i].toggleClass('disabled', colSel.auto);
}
});
if (wo.columnSelector_mediaquery) {
colSel.$auto = $( wo.columnSelector_layout.replace(/\{name\}/g, wo.columnSelector_mediaqueryName) ).prependTo(colSel.$container);
colSel.$auto
// needed in case the input in the layout is not wrapped
.find('input').add( colSel.$auto.filter('input') )
.attr('data-column', 'auto')
.prop('checked', colSel.auto)
.toggleClass( wo.columnSelector_cssChecked, colSel.auto )
.on('change', function(){
tsColSel.updateAuto(c, wo, $(this));
}).change();
tsColSel.updateBreakpoints(c, wo);
}
// Add a bind on update to re-run col setup
c.$table.off('update' + namespace).on('update' + namespace, function() {
tsColSel.updateCols(c, wo);
});
}
},
tsColSel.updateCols(c, wo);
// copy the column selector to a popup/tooltip
if (c.selector.$popup) {
c.selector.$popup.find('.tablesorter-column-selector')
.html( colSel.$container.html() )
.find('input').each(function(){
var indx = $(this).attr('data-column');
$(this).prop( 'checked', indx === 'auto' ? colSel.auto : colSel.states[indx] );
});
}
if (wo.columnSelector_saveColumns && ts.storage) {
ts.storage( c.$table[0], 'tablesorter-columnSelector-auto', { auto : colSel.auto } );
}
// trigger columnUpdate if auto is true (it gets skipped in updateCols()
if (colSel.auto) {
c.$table.trigger('columnUpdate');
}
},
updateAuto: function(c, wo, $el) {
var colSel = c.selector;
colSel.auto = $el.prop('checked') || false;
$.each( colSel.$checkbox, function(i, $cb){
if ($cb) {
$cb[0].disabled = colSel.auto;
colSel.$wrapper[i].toggleClass('disabled', colSel.auto);
updateBreakpoints: function(c, wo) {
var priority, column, breaks, temp,
colSel = c.selector,
prefix = c.namespace + 'columnselector',
mediaAll = [],
breakpts = '';
if (wo.columnSelector_mediaquery && !colSel.auto) {
colSel.$breakpoints.prop('disabled', true);
colSel.$style.prop('disabled', false);
return;
}
});
if (wo.columnSelector_mediaquery) {
tsColSel.updateBreakpoints(c, wo);
}
tsColSel.updateCols(c, wo);
// copy the column selector to a popup/tooltip
if (c.selector.$popup) {
c.selector.$popup.find('.tablesorter-column-selector')
.html( colSel.$container.html() )
.find('input').each(function(){
var indx = $(this).attr('data-column');
$(this).prop( 'checked', indx === 'auto' ? colSel.auto : colSel.states[indx] );
// only 6 breakpoints (same as jQuery Mobile)
for (priority = 0; priority < 6; priority++){
/*jshint loopfunc:true */
breaks = [];
c.$headers.filter('[' + wo.columnSelector_priority + '=' + (priority + 1) + ']').each(function(){
column = parseInt($(this).attr('data-column'), 10) + 1;
temp = ' col:nth-child(' + column + ')';
breaks.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr th:nth-child(' + column + ')';
breaks.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr td:nth-child(' + column + ')';
breaks.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
});
}
if (wo.columnSelector_saveColumns && ts.storage) {
ts.storage( c.$table[0], 'tablesorter-columnSelector-auto', { auto : colSel.auto } );
}
// trigger columnUpdate if auto is true (it gets skipped in updateCols()
if (colSel.auto) {
if (breaks.length) {
mediaAll = mediaAll.concat( breaks );
breakpts += tsColSel.queryBreak
.replace(/\[size\]/g, wo.columnSelector_breakpoints[priority])
.replace(/\[columns\]/g, breaks.join(','));
}
}
if (colSel.$style) {
colSel.$style.prop('disabled', true);
}
if (mediaAll.length) {
colSel.$breakpoints
.prop('disabled', false)
.html( tsColSel.queryAll.replace(/\[columns\]/g, mediaAll.join(',')) + breakpts );
}
},
updateCols: function(c, wo) {
if (wo.columnSelector_mediaquery && c.selector.auto || c.selector.isInitializing) {
return;
}
var column, temp,
colSel = c.selector,
styles = [],
prefix = c.namespace + 'columnselector';
colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
if (!this.checked) {
column = parseInt( $(this).attr('data-column'), 10 ) + 1;
temp = ' col:nth-child(' + column + ')';
styles.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr th:nth-child(' + column + ')';
styles.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr td:nth-child(' + column + ')';
styles.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
}
$(this).toggleClass( wo.columnSelector_cssChecked, this.checked );
});
if (wo.columnSelector_mediaquery){
colSel.$breakpoints.prop('disabled', true);
}
if (colSel.$style) {
colSel.$style.prop('disabled', false).html( styles.length ? styles.join(',') + ' { display: none; }' : '' );
}
if (wo.columnSelector_saveColumns && ts.storage) {
ts.storage( c.$table[0], 'tablesorter-columnSelector', colSel.states );
}
c.$table.trigger('columnUpdate');
}
},
},
updateBreakpoints: function(c, wo) {
var priority, column, breaks, temp,
colSel = c.selector,
prefix = c.namespace + 'columnselector',
mediaAll = [],
breakpts = '';
if (wo.columnSelector_mediaquery && !colSel.auto) {
colSel.$breakpoints.prop('disabled', true);
colSel.$style.prop('disabled', false);
return;
}
// only 6 breakpoints (same as jQuery Mobile)
for (priority = 0; priority < 6; priority++){
/*jshint loopfunc:true */
breaks = [];
c.$headers.filter('[' + wo.columnSelector_priority + '=' + (priority + 1) + ']').each(function(){
column = parseInt($(this).attr('data-column'), 10) + 1;
temp = ' col:nth-child(' + column + ')';
breaks.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr th:nth-child(' + column + ')';
breaks.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr td:nth-child(' + column + ')';
breaks.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
});
if (breaks.length) {
mediaAll = mediaAll.concat( breaks );
breakpts += tsColSel.queryBreak
.replace(/\[size\]/g, wo.columnSelector_breakpoints[priority])
.replace(/\[columns\]/g, breaks.join(','));
}
}
if (colSel.$style) {
colSel.$style.prop('disabled', true);
}
if (mediaAll.length) {
colSel.$breakpoints
.prop('disabled', false)
.html( tsColSel.queryAll.replace(/\[columns\]/g, mediaAll.join(',')) + breakpts );
}
},
updateCols: function(c, wo) {
if (wo.columnSelector_mediaquery && c.selector.auto || c.selector.isInitializing) {
return;
}
var column, temp,
colSel = c.selector,
styles = [],
prefix = c.namespace + 'columnselector';
colSel.$container.find('input[data-column]').filter('[data-column!="auto"]').each(function(){
if (!this.checked) {
column = parseInt( $(this).attr('data-column'), 10 ) + 1;
temp = ' col:nth-child(' + column + ')';
styles.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr th:nth-child(' + column + ')';
styles.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
temp = ' tr td:nth-child(' + column + ')';
styles.push(prefix + temp + ',' + prefix + '_extra_table' + temp);
}
$(this).toggleClass( wo.columnSelector_cssChecked, this.checked );
});
if (wo.columnSelector_mediaquery){
colSel.$breakpoints.prop('disabled', true);
}
if (colSel.$style) {
colSel.$style.prop('disabled', false).html( styles.length ? styles.join(',') + ' { display: none; }' : '' );
}
if (wo.columnSelector_saveColumns && ts.storage) {
ts.storage( c.$table[0], 'tablesorter-columnSelector', colSel.states );
}
c.$table.trigger('columnUpdate');
},
attachTo : function(table, elm) {
table = $(table)[0];
var colSel, wo, indx,
c = table.config,
$popup = $(elm);
if ($popup.length && c) {
if (!$popup.find('.tablesorter-column-selector').length) {
// add a wrapper to add the selector into, in case the popup has other content
$popup.append('<span class="tablesorter-column-selector"></span>');
}
colSel = c.selector;
wo = c.widgetOptions;
$popup.find('.tablesorter-column-selector')
.html( colSel.$container.html() )
.find('input').each(function(){
var indx = $(this).attr('data-column'),
isChecked = indx === 'auto' ? colSel.auto : colSel.states[indx];
$(this)
.toggleClass( wo.columnSelector_cssChecked, isChecked )
.prop( 'checked', isChecked );
attachTo : function(table, elm) {
table = $(table)[0];
var colSel, wo, indx,
c = table.config,
$popup = $(elm);
if ($popup.length && c) {
if (!$popup.find('.tablesorter-column-selector').length) {
// add a wrapper to add the selector into, in case the popup has other content
$popup.append('<span class="tablesorter-column-selector"></span>');
}
colSel = c.selector;
wo = c.widgetOptions;
$popup.find('.tablesorter-column-selector')
.html( colSel.$container.html() )
.find('input').each(function(){
var indx = $(this).attr('data-column'),
isChecked = indx === 'auto' ? colSel.auto : colSel.states[indx];
$(this)
.toggleClass( wo.columnSelector_cssChecked, isChecked )
.prop( 'checked', isChecked );
});
colSel.$popup = $popup.on('change', 'input', function(){
// data input
indx = $(this).toggleClass( wo.columnSelector_cssChecked, this.checked ).attr('data-column');
// update original popup
colSel.$container.find('input[data-column="' + indx + '"]')
.prop('checked', this.checked)
.trigger('change');
});
colSel.$popup = $popup.on('change', 'input', function(){
// data input
indx = $(this).toggleClass( wo.columnSelector_cssChecked, this.checked ).attr('data-column');
// update original popup
colSel.$container.find('input[data-column="' + indx + '"]')
.prop('checked', this.checked)
.trigger('change');
});
}
}
}
};
};
ts.addWidget({
id: "columnSelector",
priority: 10,
options: {
// target the column selector markup
columnSelector_container : null,
// column status, true = display, false = hide
// disable = do not display on list
columnSelector_columns : {},
// remember selected columns
columnSelector_saveColumns: true,
ts.addWidget({
id: 'columnSelector',
priority: 10,
options: {
// target the column selector markup
columnSelector_container : null,
// column status, true = display, false = hide
// disable = do not display on list
columnSelector_columns : {},
// remember selected columns
columnSelector_saveColumns: true,
// container layout
columnSelector_layout : '<label><input type="checkbox">{name}</label>',
// data attribute containing column name to use in the selector container
columnSelector_name : 'data-selector-name',
// container layout
columnSelector_layout : '<label><input type="checkbox">{name}</label>',
// data attribute containing column name to use in the selector container
columnSelector_name : 'data-selector-name',
/* Responsive Media Query settings */
// enable/disable mediaquery breakpoints
columnSelector_mediaquery: true,
// toggle checkbox name
columnSelector_mediaqueryName: 'Auto: ',
// breakpoints checkbox initial setting
columnSelector_mediaqueryState: true,
// responsive table hides columns with priority 1-6 at these breakpoints
// see http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/#Applyingapresetbreakpoint
// *** set to false to disable ***
columnSelector_breakpoints : [ '20em', '30em', '40em', '50em', '60em', '70em' ],
// data attribute containing column priority
// duplicates how jQuery mobile uses priorities:
// http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/
columnSelector_priority : 'data-priority',
// 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'
/* Responsive Media Query settings */
// enable/disable mediaquery breakpoints
columnSelector_mediaquery: true,
// toggle checkbox name
columnSelector_mediaqueryName: 'Auto: ',
// breakpoints checkbox initial setting
columnSelector_mediaqueryState: true,
// responsive table hides columns with priority 1-6 at these breakpoints
// see http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/#Applyingapresetbreakpoint
// *** set to false to disable ***
columnSelector_breakpoints : [ '20em', '30em', '40em', '50em', '60em', '70em' ],
// data attribute containing column priority
// duplicates how jQuery mobile uses priorities:
// http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/
columnSelector_priority : 'data-priority',
// 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'
},
init: function(table, thisWidget, c, wo) {
tsColSel.init(table, c, wo);
},
remove: function(table, c, wo, refreshing) {
if (refreshing) { return; }
var csel = c.selector;
csel.$container.empty();
if (csel.$popup) { csel.$popup.empty(); }
csel.$style.remove();
csel.$breakpoints.remove();
c.$table.off('updateAll' + namespace + ' update' + namespace);
}
},
init: function(table, thisWidget, c, wo) {
tsColSel.init(table, c, wo);
},
remove: function(table, c, wo, refreshing) {
if (refreshing) { return; }
var csel = c.selector;
csel.$container.empty();
if (csel.$popup) { csel.$popup.empty(); }
csel.$style.remove();
csel.$breakpoints.remove();
c.$table.off('updateAll' + namespace + ' update' + namespace);
}
});
});
})(jQuery);

View File

@ -1,78 +1,78 @@
/*! Widget: columns */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
'use strict';
var ts = $.tablesorter || {};
ts.addWidget({
id: "columns",
priority: 30,
options : {
columns : [ "primary", "secondary", "tertiary" ]
},
format: function(table, c, wo) {
var $tbody, tbodyIndex, $rows, rows, $row, $cells, remove, indx,
ts.addWidget({
id: 'columns',
priority: 30,
options : {
columns : [ 'primary', 'secondary', 'tertiary' ]
},
format: function(table, c, wo) {
var $tbody, tbodyIndex, $rows, rows, $row, $cells, remove, indx,
$table = c.$table,
$tbodies = c.$tbodies,
sortList = c.sortList,
len = sortList.length,
// removed c.widgetColumns support
css = wo && wo.columns || [ "primary", "secondary", "tertiary" ],
css = wo && wo.columns || [ 'primary', 'secondary', 'tertiary' ],
last = css.length - 1;
remove = css.join(' ');
// check if there is a sort (on initialization there may not be one)
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // detach tbody
$rows = $tbody.children('tr');
// loop through the visible rows
$rows.each(function() {
$row = $(this);
if (this.style.display !== 'none') {
// remove all columns class names
$cells = $row.children().removeClass(remove);
// add appropriate column class names
if (sortList && sortList[0]) {
// primary sort column class
$cells.eq(sortList[0][0]).addClass(css[0]);
if (len > 1) {
for (indx = 1; indx < len; indx++) {
// secondary, tertiary, etc sort column classes
$cells.eq(sortList[indx][0]).addClass( css[indx] || css[last] );
// check if there is a sort (on initialization there may not be one)
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // detach tbody
$rows = $tbody.children('tr');
// loop through the visible rows
$rows.each(function() {
$row = $(this);
if (this.style.display !== 'none') {
// remove all columns class names
$cells = $row.children().removeClass(remove);
// add appropriate column class names
if (sortList && sortList[0]) {
// primary sort column class
$cells.eq(sortList[0][0]).addClass(css[0]);
if (len > 1) {
for (indx = 1; indx < len; indx++) {
// secondary, tertiary, etc sort column classes
$cells.eq(sortList[indx][0]).addClass( css[indx] || css[last] );
}
}
}
}
}
});
ts.processTbody(table, $tbody, false);
}
// add classes to thead and tfoot
rows = wo.columns_thead !== false ? ['thead tr'] : [];
if (wo.columns_tfoot !== false) {
rows.push('tfoot tr');
}
if (rows.length) {
$rows = $table.find( rows.join(',') ).children().removeClass(remove);
if (len) {
for (indx = 0; indx < len; indx++) {
// add primary. secondary, tertiary, etc sort column classes
$rows.filter('[data-column="' + sortList[indx][0] + '"]').addClass(css[indx] || css[last]);
});
ts.processTbody(table, $tbody, false);
}
// add classes to thead and tfoot
rows = wo.columns_thead !== false ? [ 'thead tr' ] : [];
if (wo.columns_tfoot !== false) {
rows.push('tfoot tr');
}
if (rows.length) {
$rows = $table.find( rows.join(',') ).children().removeClass(remove);
if (len) {
for (indx = 0; indx < len; indx++) {
// add primary. secondary, tertiary, etc sort column classes
$rows.filter('[data-column="' + sortList[indx][0] + '"]').addClass(css[indx] || css[last]);
}
}
}
},
remove: function(table, c, wo) {
var tbodyIndex, $tbody,
$tbodies = c.$tbodies,
remove = (wo.columns || [ 'primary', 'secondary', 'tertiary' ]).join(' ');
c.$headers.removeClass(remove);
c.$table.children('tfoot').children('tr').children('th, td').removeClass(remove);
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
$tbody.children('tr').each(function() {
$(this).children().removeClass(remove);
});
ts.processTbody(table, $tbody, false); // restore tbody
}
}
},
remove: function(table, c, wo) {
var tbodyIndex, $tbody,
$tbodies = c.$tbodies,
remove = (wo.columns || [ "primary", "secondary", "tertiary" ]).join(' ');
c.$headers.removeClass(remove);
c.$table.children('tfoot').children('tr').children('th, td').removeClass(remove);
for (tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) {
$tbody = ts.processTbody(table, $tbodies.eq(tbodyIndex), true); // remove tbody
$tbody.children('tr').each(function() {
$(this).children().removeClass(remove);
});
ts.processTbody(table, $tbody, false); // restore tbody
}
}
});
});
})(jQuery);

View File

@ -7,254 +7,254 @@
;( function( $ ){
'use strict';
var tse = $.tablesorter.editable = {
namespace : '.tseditable',
// last edited class name
lastEdited: 'tseditable-last-edited-cell',
var tse = $.tablesorter.editable = {
namespace : '.tseditable',
// last edited class name
lastEdited: 'tseditable-last-edited-cell',
editComplete: function( c, wo, $cell, refocus ) {
c.$table
.find( '.' + tse.lastEdited )
.removeClass( tse.lastEdited )
.trigger( wo.editable_editComplete, [ c ] );
// restore focus last cell after updating
if ( refocus ) {
editComplete: function( c, wo, $cell, refocus ) {
c.$table
.find( '.' + tse.lastEdited )
.removeClass( tse.lastEdited )
.trigger( wo.editable_editComplete, [ c ] );
// restore focus last cell after updating
if ( refocus ) {
setTimeout( function() {
$cell.focus();
}, 50 );
}
},
selectAll: function( cell ) {
setTimeout( function() {
$cell.focus();
}, 50 );
}
},
selectAll: function( cell ) {
setTimeout( function() {
// select all text in contenteditable
// see http://stackoverflow.com/a/6150060/145346
var range, selection;
if ( document.body.createTextRange ) {
range = document.body.createTextRange();
range.moveToElementText( cell );
range.select();
} else if ( window.getSelection ) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents( cell );
selection.removeAllRanges();
selection.addRange( range );
}
}, 100 );
},
getColumns : function( c, wo ) {
var indx, tmp,
colIndex = [],
cols = [];
if ( !wo.editable_columnsArray && $.type( wo.editable_columns ) === 'string' && wo.editable_columns.indexOf( '-' ) >= 0 ) {
// editable_columns can contain a range string ( i.e. '2-4' )
tmp = wo.editable_columns.split( /\s*-\s*/ );
indx = parseInt( tmp[ 0 ], 10 ) || 0;
tmp = parseInt( tmp[ 1 ], 10 ) || ( c.columns - 1 );
if ( tmp > c.columns ) {
tmp = c.columns - 1;
}
for ( ; indx <= tmp; indx++ ) {
colIndex.push( indx );
cols.push( 'td:nth-child(' + ( indx + 1 ) + ')' );
}
} else if ( $.isArray( wo.editable_columns ) ) {
$.each( wo.editable_columnsArray || wo.editable_columns, function( i, col ) {
if ( col < c.columns ) {
colIndex.push( col );
cols.push( 'td:nth-child(' + ( col + 1 ) + ')' );
// select all text in contenteditable
// see http://stackoverflow.com/a/6150060/145346
var range, selection;
if ( document.body.createTextRange ) {
range = document.body.createTextRange();
range.moveToElementText( cell );
range.select();
} else if ( window.getSelection ) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents( cell );
selection.removeAllRanges();
selection.addRange( range );
}
});
}
if ( !wo.editable_columnsArray ) {
wo.editable_columnsArray = colIndex;
wo.editable_columnsArray.sort(function(a,b){ return a - b; });
}
return cols;
},
}, 100 );
},
update: function( c, wo ) {
var $t,
tmp = $( '<div>' ).wrapInner( wo.editable_wrapContent ).children().length || $.isFunction( wo.editable_wrapContent ),
cols = tse.getColumns( c, wo ).join( ',' );
// turn off contenteditable to allow dynamically setting the wo.editable_noEdit
// class on table cells - see issue #900
c.$tbodies.find( cols ).find( '[contenteditable]' ).prop( 'contenteditable', false );
// IE does not allow making TR/TH/TD cells directly editable ( issue #404 )
// so add a div or span inside ( it's faster than using wrapInner() )
c.$tbodies.find( cols ).not( '.' + wo.editable_noEdit ).each( function() {
// test for children, if they exist, then make the children editable
$t = $( this );
if ( tmp && $t.children( 'div, span' ).length === 0 ) {
$t.wrapInner( wo.editable_wrapContent );
getColumns : function( c, wo ) {
var indx, tmp,
colIndex = [],
cols = [];
if ( !wo.editable_columnsArray && $.type( wo.editable_columns ) === 'string' && wo.editable_columns.indexOf( '-' ) >= 0 ) {
// editable_columns can contain a range string ( i.e. '2-4' )
tmp = wo.editable_columns.split( /\s*-\s*/ );
indx = parseInt( tmp[ 0 ], 10 ) || 0;
tmp = parseInt( tmp[ 1 ], 10 ) || ( c.columns - 1 );
if ( tmp > c.columns ) {
tmp = c.columns - 1;
}
for ( ; indx <= tmp; indx++ ) {
colIndex.push( indx );
cols.push( 'td:nth-child(' + ( indx + 1 ) + ')' );
}
} else if ( $.isArray( wo.editable_columns ) ) {
$.each( wo.editable_columnsArray || wo.editable_columns, function( i, col ) {
if ( col < c.columns ) {
colIndex.push( col );
cols.push( 'td:nth-child(' + ( col + 1 ) + ')' );
}
});
}
if ( $t.children( 'div, span' ).length ) {
// make div/span children content editable
$t.children( 'div, span' ).not( '.' + wo.editable_noEdit ).each( function() {
var $this = $( this );
if ( !wo.editable_columnsArray ) {
wo.editable_columnsArray = colIndex;
wo.editable_columnsArray.sort(function(a, b){ return a - b; });
}
return cols;
},
update: function( c, wo ) {
var $t,
tmp = $( '<div>' ).wrapInner( wo.editable_wrapContent ).children().length || $.isFunction( wo.editable_wrapContent ),
cols = tse.getColumns( c, wo ).join( ',' );
// turn off contenteditable to allow dynamically setting the wo.editable_noEdit
// class on table cells - see issue #900
c.$tbodies.find( cols ).find( '[contenteditable]' ).prop( 'contenteditable', false );
// IE does not allow making TR/TH/TD cells directly editable ( issue #404 )
// so add a div or span inside ( it's faster than using wrapInner() )
c.$tbodies.find( cols ).not( '.' + wo.editable_noEdit ).each( function() {
// test for children, if they exist, then make the children editable
$t = $( this );
if ( tmp && $t.children( 'div, span' ).length === 0 ) {
$t.wrapInner( wo.editable_wrapContent );
}
if ( $t.children( 'div, span' ).length ) {
// make div/span children content editable
$t.children( 'div, span' ).not( '.' + wo.editable_noEdit ).each( function() {
var $this = $( this );
if ( wo.editable_trimContent ) {
$this.html( function( i, txt ) {
return $.trim( txt );
});
}
$this.prop( 'contenteditable', true );
});
} else {
if ( wo.editable_trimContent ) {
$this.html( function( i, txt ) {
$t.html( function( i, txt ) {
return $.trim( txt );
});
}
$this.prop( 'contenteditable', true );
});
} else {
if ( wo.editable_trimContent ) {
$t.html( function( i, txt ) {
return $.trim( txt );
});
}
$t.prop( 'contenteditable', true );
}
});
},
bindEvents: function( c, wo ) {
var namespace = tse.namespace;
c.$table
.off( ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
.on( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ), function() {
tse.update( c, c.widgetOptions );
})
// prevent sort initialized by user click on the header from changing the row indexing before
// updateCell can finish processing the change
.children( 'thead' )
.add( $( c.namespace + '_extra_table' ).children( 'thead' ) )
.off( 'mouseenter' + namespace )
.on( 'mouseenter' + namespace, function() {
if ( c.$table.data( 'contentFocused' ) ) {
// change to 'true' instead of element to allow focusout to process
c.$table.data( 'contentFocused', true );
$( ':focus' ).trigger( 'focusout' );
$t.prop( 'contenteditable', true );
}
});
},
c.$tbodies
.off( ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
.on( 'focus' + namespace, '[contenteditable]', function( e ) {
clearTimeout( $( this ).data( 'timer' ) );
c.$table.data( 'contentFocused', e.target );
c.table.isUpdating = true; // prevent sorting while editing
var $this = $( this ),
selAll = wo.editable_selectAll,
column = $this.closest( 'td' ).index(),
txt = $this.html();
if ( wo.editable_trimContent ) {
txt = $.trim( txt );
}
// prevent enter from adding into the content
$this
.off( 'keydown' + namespace )
.on( 'keydown' + namespace, function( e ){
if ( wo.editable_enterToAccept && e.which === 13 && !e.shiftKey ) {
e.preventDefault();
}
});
$this.data({ before : txt, original: txt });
bindEvents: function( c, wo ) {
var namespace = tse.namespace;
c.$table
.off( ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
.on( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ), function() {
tse.update( c, c.widgetOptions );
})
// prevent sort initialized by user click on the header from changing the row indexing before
// updateCell can finish processing the change
.children( 'thead' )
.add( $( c.namespace + '_extra_table' ).children( 'thead' ) )
.off( 'mouseenter' + namespace )
.on( 'mouseenter' + namespace, function() {
if ( c.$table.data( 'contentFocused' ) ) {
// change to 'true' instead of element to allow focusout to process
c.$table.data( 'contentFocused', true );
$( ':focus' ).trigger( 'focusout' );
}
});
if ( typeof wo.editable_focused === 'function' ) {
wo.editable_focused( txt, column, $this );
}
c.$tbodies
.off( ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
.on( 'focus' + namespace, '[contenteditable]', function( e ) {
clearTimeout( $( this ).data( 'timer' ) );
c.$table.data( 'contentFocused', e.target );
c.table.isUpdating = true; // prevent sorting while editing
var $this = $( this ),
selAll = wo.editable_selectAll,
column = $this.closest( 'td' ).index(),
txt = $this.html();
if ( wo.editable_trimContent ) {
txt = $.trim( txt );
}
// prevent enter from adding into the content
$this
.off( 'keydown' + namespace )
.on( 'keydown' + namespace, function( e ){
if ( wo.editable_enterToAccept && e.which === 13 && !e.shiftKey ) {
e.preventDefault();
}
});
$this.data({ before : txt, original: txt });
if ( selAll ) {
if ( typeof selAll === 'function' ) {
if ( selAll( txt, column, $this ) ) {
if ( typeof wo.editable_focused === 'function' ) {
wo.editable_focused( txt, column, $this );
}
if ( selAll ) {
if ( typeof selAll === 'function' ) {
if ( selAll( txt, column, $this ) ) {
tse.selectAll( $this[0] );
}
} else {
tse.selectAll( $this[0] );
}
} else {
tse.selectAll( $this[0] );
}
}
})
.on( 'blur focusout keydown '.split( ' ' ).join( namespace + ' ' ), '[contenteditable]', function( e ) {
if ( !c.$table.data( 'contentFocused' ) ) { return; }
var t, validate,
valid = false,
$this = $( e.target ),
txt = $this.html(),
column = $this.closest( 'td' ).index();
if ( wo.editable_trimContent ) {
txt = $.trim( txt );
}
if ( e.which === 27 ) {
// user cancelled
$this.html( $this.data( 'original' ) ).trigger( 'blur' + namespace );
c.$table.data( 'contentFocused', false );
c.table.isUpdating = false;
return false;
}
// accept on enter ( if set ), alt-enter ( always ) or if autoAccept is set and element is blurred or unfocused
t = e.which === 13 && !e.shiftKey && ( wo.editable_enterToAccept || e.altKey ) || wo.editable_autoAccept && e.type !== 'keydown';
// change if new or user hits enter ( if option set )
if ( t && $this.data( 'before' ) !== txt ) {
validate = wo.editable_validate;
valid = txt;
if ( typeof( validate ) === 'function' ) {
valid = validate( txt, $this.data( 'original' ), column, $this );
} else if ( typeof ( validate = $.tablesorter.getColumnData( c.table, validate, column ) ) === 'function' ) {
valid = validate( txt, $this.data( 'original' ), column, $this );
})
.on( 'blur focusout keydown '.split( ' ' ).join( namespace + ' ' ), '[contenteditable]', function( e ) {
if ( !c.$table.data( 'contentFocused' ) ) { return; }
var t, validate,
valid = false,
$this = $( e.target ),
txt = $this.html(),
column = $this.closest( 'td' ).index();
if ( wo.editable_trimContent ) {
txt = $.trim( txt );
}
if ( t && valid !== false ) {
c.$table.find( '.' + tse.lastEdited ).removeClass( tse.lastEdited );
$this
.addClass( tse.lastEdited )
.html( valid )
.data( 'before', valid )
.data( 'original', valid )
.trigger( 'change' );
c.$table.trigger( 'updateCell', [ $this.closest( 'td' ), false, function() {
if ( wo.editable_autoResort ) {
setTimeout( function() {
c.$table.trigger( 'sorton', [ c.sortList, function() {
tse.editComplete( c, wo, c.$table.data( 'contentFocused' ), true );
}, true ] );
}, 10 );
} else {
tse.editComplete( c, wo, c.$table.data( 'contentFocused' ) );
}
} ] );
if ( e.which === 27 ) {
// user cancelled
$this.html( $this.data( 'original' ) ).trigger( 'blur' + namespace );
c.$table.data( 'contentFocused', false );
c.table.isUpdating = false;
return false;
}
} else if ( !valid && e.type !== 'keydown' ) {
clearTimeout( $this.data( 'timer' ) );
$this.data( 'timer', setTimeout( function() {
c.table.isUpdating = false; // clear flag or sorting will be disabled
// accept on enter ( if set ), alt-enter ( always ) or if autoAccept is set and element is blurred or unfocused
t = e.which === 13 && !e.shiftKey && ( wo.editable_enterToAccept || e.altKey ) || wo.editable_autoAccept && e.type !== 'keydown';
// change if new or user hits enter ( if option set )
if ( t && $this.data( 'before' ) !== txt ) {
if ( $.isFunction( wo.editable_blur ) ) {
txt = $this.html();
wo.editable_blur( wo.editable_trimContent ? $.trim( txt ) : txt, column, $this );
validate = wo.editable_validate;
valid = txt;
if ( typeof validate === 'function' ) {
valid = validate( txt, $this.data( 'original' ), column, $this );
} else if ( typeof ( validate = $.tablesorter.getColumnData( c.table, validate, column ) ) === 'function' ) {
valid = validate( txt, $this.data( 'original' ), column, $this );
}
}, 100 ) );
// restore original content on blur
$this.html( $this.data( 'original' ) );
}
});
},
destroy : function( c, wo ) {
var namespace = tse.namespace,
cols = tse.getColumns( c, wo ),
tmp = ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
c.$table.off( tmp );
if ( t && valid !== false ) {
c.$table.find( '.' + tse.lastEdited ).removeClass( tse.lastEdited );
$this
.addClass( tse.lastEdited )
.html( valid )
.data( 'before', valid )
.data( 'original', valid )
.trigger( 'change' );
c.$table.trigger( 'updateCell', [ $this.closest( 'td' ), false, function() {
if ( wo.editable_autoResort ) {
setTimeout( function() {
c.$table.trigger( 'sorton', [ c.sortList, function() {
tse.editComplete( c, wo, c.$table.data( 'contentFocused' ), true );
}, true ] );
}, 10 );
} else {
tse.editComplete( c, wo, c.$table.data( 'contentFocused' ) );
}
} ] );
return false;
}
} else if ( !valid && e.type !== 'keydown' ) {
clearTimeout( $this.data( 'timer' ) );
$this.data( 'timer', setTimeout( function() {
c.table.isUpdating = false; // clear flag or sorting will be disabled
tmp = ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
c.$tbodies
.off( tmp )
.find( cols.join( ',' ) )
.find( '[contenteditable]' )
.prop( 'contenteditable', false );
}
if ( $.isFunction( wo.editable_blur ) ) {
txt = $this.html();
wo.editable_blur( wo.editable_trimContent ? $.trim( txt ) : txt, column, $this );
}
}, 100 ) );
// restore original content on blur
$this.html( $this.data( 'original' ) );
}
});
},
destroy : function( c, wo ) {
var namespace = tse.namespace,
cols = tse.getColumns( c, wo ),
};
tmp = ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
c.$table.off( tmp );
tmp = ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
c.$tbodies
.off( tmp )
.find( cols.join( ',' ) )
.find( '[contenteditable]' )
.prop( 'contenteditable', false );
}
};
$.tablesorter.addWidget({
id: 'editable',

View File

@ -8,422 +8,421 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter || {},
var ts = $.tablesorter || {},
// compare option selector class name (jQuery selector)
compareSelect = '.compare-select',
// compare option selector class name (jQuery selector)
compareSelect = '.compare-select',
tsff = ts.filterFormatter = $.extend( {}, ts.filterFormatter, {
tsff = ts.filterFormatter = $.extend( {}, ts.filterFormatter, {
addCompare: function($cell, indx, options){
if (options.compare && $.isArray(options.compare) && options.compare.length > 1) {
var opt = '',
compareSelectClass = [ compareSelect.slice(1), ' ' + compareSelect.slice(1), '' ],
txt = options.cellText ? '<label class="' + compareSelectClass.join('-label') + indx + '">' + options.cellText + '</label>' : '';
$.each(options.compare, function(i, c){
opt += '<option ' + (options.selected === i ? 'selected' : '') + '>' + c + '</option>';
});
$cell
.wrapInner('<div class="' + compareSelectClass.join('-wrapper') + indx + '" />')
.prepend( txt + '<select class="' + compareSelectClass.join('') + indx + '" />' )
.find('select')
.append(opt);
}
},
updateCompare : function($cell, $input, o) {
var val = $input.val() || '',
num = val.replace(/\s*?[><=]\s*?/g, ''),
compare = val.match(/[><=]/g) || '';
if (o.compare) {
if ($.isArray(o.compare)){
compare = (compare || []).join('') || o.compare[o.selected || 0];
addCompare: function($cell, indx, options){
if (options.compare && $.isArray(options.compare) && options.compare.length > 1) {
var opt = '',
compareSelectClass = [ compareSelect.slice(1), ' ' + compareSelect.slice(1), '' ],
txt = options.cellText ? '<label class="' + compareSelectClass.join('-label') + indx + '">' + options.cellText + '</label>' : '';
$.each(options.compare, function(i, c){
opt += '<option ' + (options.selected === i ? 'selected' : '') + '>' + c + '</option>';
});
$cell
.wrapInner('<div class="' + compareSelectClass.join('-wrapper') + indx + '" />')
.prepend( txt + '<select class="' + compareSelectClass.join('') + indx + '" />' )
.find('select')
.append(opt);
}
$cell.find(compareSelect).val( compare );
}
return [ val, num ];
},
},
/**********************\
HTML5 Number (spinner)
\**********************/
html5Number : function($cell, indx, def5Num) {
var t, o = $.extend({
value : 0,
min : 0,
max : 100,
step : 1,
delayed : true,
disabled : false,
addToggle : false,
exactMatch : false,
cellText : '',
compare : '',
skipTest: false
}, def5Num),
$input,
// test browser for HTML5 range support
$number = $('<input type="number" style="visibility:hidden;" value="test">').appendTo($cell),
// test if HTML5 number is supported - from Modernizr
numberSupported = o.skipTest || $number.attr('type') === 'number' && $number.val() !== 'test',
$shcell = [],
c = $cell.closest('table')[0].config,
updateNumber = function(delayed, notrigger){
var chkd = o.addToggle ? $cell.find('.toggle').is(':checked') : true,
v = $cell.find('.number').val(),
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
$input
// add equal to the beginning, so we filter exact numbers
.val( !o.addToggle || chkd ? (compare ? compare : o.exactMatch ? '=' : '') + v : '' )
.trigger( notrigger ? '' : 'search', searchType ).end()
.find('.number').val(v);
if ($cell.find('.number').length) {
$cell.find('.number')[0].disabled = (o.disabled || !chkd);
}
// update sticky header cell
if ($shcell.length) {
$shcell.find('.number').val(v)[0].disabled = (o.disabled || !chkd);
$shcell.find(compareSelect).val(compare);
if (o.addToggle) {
$shcell.find('.toggle')[0].checked = chkd;
updateCompare : function($cell, $input, o) {
var val = $input.val() || '',
num = val.replace(/\s*?[><=]\s*?/g, ''),
compare = val.match(/[><=]/g) || '';
if (o.compare) {
if ($.isArray(o.compare)){
compare = (compare || []).join('') || o.compare[o.selected || 0];
}
$cell.find(compareSelect).val( compare );
}
};
$number.remove();
return [ val, num ];
},
if (numberSupported) {
t = o.addToggle ? '<div class="button"><input id="html5button' + indx + '" type="checkbox" class="toggle" />' +
'<label for="html5button' + indx + '"></label></div>' : '';
t += '<input class="number" type="number" min="' + o.min + '" max="' + o.max + '" value="' +
o.value + '" step="' + o.step + '" />';
// add HTML5 number (spinner)
$cell
.append(t + '<input type="hidden" />')
.find('.toggle, .number').bind('change', function(){
updateNumber();
})
.closest('thead').find('th[data-column=' + indx + ']')
.addClass('filter-parsed') // get exact numbers from column
// on reset
.closest('table').bind('filterReset', function(){
if ($.isArray(o.compare)) {
$cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
}
// turn off the toggle checkbox
/**********************\
HTML5 Number (spinner)
\**********************/
html5Number : function($cell, indx, def5Num) {
var t, o = $.extend({
value : 0,
min : 0,
max : 100,
step : 1,
delayed : true,
disabled : false,
addToggle : false,
exactMatch : false,
cellText : '',
compare : '',
skipTest: false
}, def5Num),
$input,
// test browser for HTML5 range support
$number = $('<input type="number" style="visibility:hidden;" value="test">').appendTo($cell),
// test if HTML5 number is supported - from Modernizr
numberSupported = o.skipTest || $number.attr('type') === 'number' && $number.val() !== 'test',
$shcell = [],
c = $cell.closest('table')[0].config,
updateNumber = function(delayed, notrigger){
var chkd = o.addToggle ? $cell.find('.toggle').is(':checked') : true,
v = $cell.find('.number').val(),
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
$input
// add equal to the beginning, so we filter exact numbers
.val( !o.addToggle || chkd ? (compare ? compare : o.exactMatch ? '=' : '') + v : '' )
.trigger( notrigger ? '' : 'search', searchType ).end()
.find('.number').val(v);
if ($cell.find('.number').length) {
$cell.find('.number')[0].disabled = (o.disabled || !chkd);
}
// update sticky header cell
if ($shcell.length) {
$shcell.find('.number').val(v)[0].disabled = (o.disabled || !chkd);
$shcell.find(compareSelect).val(compare);
if (o.addToggle) {
$cell.find('.toggle')[0].checked = false;
if ($shcell.length) {
$shcell.find('.toggle')[0].checked = false;
}
$shcell.find('.toggle')[0].checked = chkd;
}
$cell.find('.number').val( o.value );
setTimeout(function(){
}
};
$number.remove();
if (numberSupported) {
t = o.addToggle ? '<div class="button"><input id="html5button' + indx + '" type="checkbox" class="toggle" />' +
'<label for="html5button' + indx + '"></label></div>' : '';
t += '<input class="number" type="number" min="' + o.min + '" max="' + o.max + '" value="' +
o.value + '" step="' + o.step + '" />';
// add HTML5 number (spinner)
$cell
.append(t + '<input type="hidden" />')
.find('.toggle, .number').bind('change', function(){
updateNumber();
}, 0);
});
$input = $cell.find('input[type=hidden]').bind('change', function(){
$cell.find('.number').val( this.value );
updateNumber();
});
// update slider from hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
var val = tsff.updateCompare($cell, $input, o)[0] || o.value;
$cell.find('.number').val( ((val || '') + '').replace(/[><=]/g,'') );
updateNumber(false, true);
ts.filter.formatterUpdated($cell, indx);
});
if (o.compare) {
// add compare select
tsff.addCompare($cell, indx, o);
$cell.find(compareSelect).bind('change', function(){
})
.closest('thead').find('th[data-column=' + indx + ']')
.addClass('filter-parsed') // get exact numbers from column
// on reset
.closest('table').bind('filterReset', function(){
if ($.isArray(o.compare)) {
$cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
}
// turn off the toggle checkbox
if (o.addToggle) {
$cell.find('.toggle')[0].checked = false;
if ($shcell.length) {
$shcell.find('.toggle')[0].checked = false;
}
}
$cell.find('.number').val( o.value );
setTimeout(function(){
updateNumber();
}, 0);
});
$input = $cell.find('input[type=hidden]').bind('change', function(){
$cell.find('.number').val( this.value );
updateNumber();
});
}
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
$shcell
.append(t)
.find('.toggle, .number').bind('change', function(){
$cell.find('.number').val( $(this).val() );
updateNumber();
});
// update slider from hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
var val = tsff.updateCompare($cell, $input, o)[0] || o.value;
$cell.find('.number').val( ((val || '') + '').replace(/[><=]/g, '') );
updateNumber(false, true);
ts.filter.formatterUpdated($cell, indx);
});
if (o.compare) {
// add compare select
tsff.addCompare($shcell, indx, o);
$shcell.find(compareSelect).bind('change', function(){
$cell.find(compareSelect).val( $(this).val() );
tsff.addCompare($cell, indx, o);
$cell.find(compareSelect).bind('change', function(){
updateNumber();
});
}
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
$shcell
.append(t)
.find('.toggle, .number').bind('change', function(){
$cell.find('.number').val( $(this).val() );
updateNumber();
});
if (o.compare) {
// add compare select
tsff.addCompare($shcell, indx, o);
$shcell.find(compareSelect).bind('change', function(){
$cell.find(compareSelect).val( $(this).val() );
updateNumber();
});
}
updateNumber();
});
updateNumber();
});
updateNumber();
}
return numberSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
},
/**********************\
HTML5 range slider
\**********************/
html5Range : function($cell, indx, def5Range) {
var o = $.extend({
value : 0,
min : 0,
max : 100,
step : 1,
delayed : true,
valueToHeader : true,
exactMatch : true,
cellText : '',
compare : '',
allText : 'all',
skipTest : false
}, def5Range),
$input,
// test browser for HTML5 range support
$range = $('<input type="range" style="visibility:hidden;" value="test">').appendTo($cell),
// test if HTML5 range is supported - from Modernizr (but I left out the method to detect in Safari 2-4)
// see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/inputtypes.js
rangeSupported = o.skipTest || $range.attr('type') === 'range' && $range.val() !== 'test',
$shcell = [],
c = $cell.closest('table')[0].config,
updateRange = function(v, delayed, notrigger){
/*jshint eqeqeq:false */
// hidden input changes may include compare symbols
v = ( typeof v === "undefined" ? $input.val() : v ).toString().replace(/[<>=]/g,'') || o.value;
var compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
t = ' (' + (compare ? compare + v : v == o.min ? o.allText : v) + ')',
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
$cell.find('input[type=hidden]')
// add equal to the beginning, so we filter exact numbers
.val( ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) ) )
//( val == o.min ? '' : val + (o.exactMatch ? '=' : ''))
.trigger( notrigger ? '' : 'search', searchType ).end()
.find('.range').val(v);
// or add current value to the header cell, if desired
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
// update sticky header cell
if ($shcell.length) {
$shcell
.find('.range').val(v).end()
.find(compareSelect).val( compare );
$shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
}
};
$range.remove();
if (rangeSupported) {
// add HTML5 range
$cell
.html('<input type="hidden"><input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
.closest('thead').find('th[data-column=' + indx + ']')
.addClass('filter-parsed') // get exact numbers from column
// add span to header for the current slider value
.find('.tablesorter-header-inner').append('<span class="curvalue" />');
// hidden filter update namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
return numberSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
},
/**********************\
HTML5 range slider
\**********************/
html5Range : function($cell, indx, def5Range) {
var o = $.extend({
value : 0,
min : 0,
max : 100,
step : 1,
delayed : true,
valueToHeader : true,
exactMatch : true,
cellText : '',
compare : '',
allText : 'all',
skipTest : false
}, def5Range),
$input,
// test browser for HTML5 range support
$range = $('<input type="range" style="visibility:hidden;" value="test">').appendTo($cell),
// test if HTML5 range is supported - from Modernizr (but I left out the method to detect in Safari 2-4)
// see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/inputtypes.js
rangeSupported = o.skipTest || $range.attr('type') === 'range' && $range.val() !== 'test',
$shcell = [],
c = $cell.closest('table')[0].config,
updateRange = function(v, delayed, notrigger){
/*jshint eqeqeq:false */
var v = this.value,
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '';
if (v !== this.lastValue) {
this.lastValue = ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) );
this.value = this.lastValue;
updateRange( v );
// hidden input changes may include compare symbols
v = ( typeof v === 'undefined' ? $input.val() : v ).toString().replace(/[<>=]/g, '') || o.value;
var compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
t = ' (' + (compare ? compare + v : v == o.min ? o.allText : v) + ')',
searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
$cell.find('input[type=hidden]')
// add equal to the beginning, so we filter exact numbers
.val( ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) ) )
// ( val == o.min ? '' : val + (o.exactMatch ? '=' : ''))
.trigger( notrigger ? '' : 'search', searchType ).end()
.find('.range').val(v);
// or add current value to the header cell, if desired
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
// update sticky header cell
if ($shcell.length) {
$shcell
.find('.range').val(v).end()
.find(compareSelect).val( compare );
$shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
}
});
};
$range.remove();
$cell.find('.range').bind('change', function(){
updateRange( this.value );
});
// update spinner from hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
var val = tsff.updateCompare($cell, $input, o)[0];
$cell.find('.range').val( val );
updateRange(val, false, true);
ts.filter.formatterUpdated($cell, indx);
});
if (o.compare) {
// add compare select
tsff.addCompare($cell, indx, o);
$cell.find(compareSelect).bind('change', function(){
updateRange();
if (rangeSupported) {
// add HTML5 range
$cell
.html('<input type="hidden"><input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
.closest('thead').find('th[data-column=' + indx + ']')
.addClass('filter-parsed') // get exact numbers from column
// add span to header for the current slider value
.find('.tablesorter-header-inner').append('<span class="curvalue" />');
// hidden filter update namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
/*jshint eqeqeq:false */
var v = this.value,
compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '';
if (v !== this.lastValue) {
this.lastValue = ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) );
this.value = this.lastValue;
updateRange( v );
}
});
}
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
$shcell
.html('<input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
.find('.range').bind('change', function(){
updateRange( $shcell.find('.range').val() );
});
updateRange();
$cell.find('.range').bind('change', function(){
updateRange( this.value );
});
// update spinner from hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
var val = tsff.updateCompare($cell, $input, o)[0];
$cell.find('.range').val( val );
updateRange(val, false, true);
ts.filter.formatterUpdated($cell, indx);
});
if (o.compare) {
// add compare select
tsff.addCompare($shcell, indx, o);
$shcell.find(compareSelect).bind('change', function(){
$cell.find(compareSelect).val( $(this).val() );
tsff.addCompare($cell, indx, o);
$cell.find(compareSelect).bind('change', function(){
updateRange();
});
}
});
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
$shcell
.html('<input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
.find('.range').bind('change', function(){
updateRange( $shcell.find('.range').val() );
});
updateRange();
// on reset
$cell.closest('table').bind('filterReset', function(){
if ($.isArray(o.compare)) {
$cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
}
setTimeout(function(){
updateRange(o.value, false, true);
}, 0);
});
updateRange();
if (o.compare) {
// add compare select
tsff.addCompare($shcell, indx, o);
$shcell.find(compareSelect).bind('change', function(){
$cell.find(compareSelect).val( $(this).val() );
updateRange();
});
}
}
});
return rangeSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
},
// on reset
$cell.closest('table').bind('filterReset', function(){
if ($.isArray(o.compare)) {
$cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
}
setTimeout(function(){
updateRange(o.value, false, true);
}, 0);
});
updateRange();
/**********************\
HTML5 Color picker
\**********************/
html5Color: function($cell, indx, defColor) {
var t, o = $.extend({
value : '#000000',
disabled : false,
addToggle : true,
exactMatch : true,
valueToHeader : false,
skipTest : false
}, defColor),
$input,
// Add a hidden input to hold the range values
$color = $('<input type="color" style="visibility:hidden;" value="test">').appendTo($cell),
// test if HTML5 color is supported - from Modernizr
colorSupported = o.skipTest || $color.attr('type') === 'color' && $color.val() !== 'test',
$shcell = [],
c = $cell.closest('table')[0].config,
updateColor = function(v, notrigger){
v = ( typeof v === "undefined" ? $input.val() : v ).toString().replace('=','') || o.value;
var chkd = true,
t = ' (' + v + ')';
if (o.addToggle) {
chkd = $cell.find('.toggle').is(':checked');
}
if ($cell.find('.colorpicker').length) {
$cell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
}
$input
.val( chkd ? v + (o.exactMatch ? '=' : '') : '' )
.trigger( !c.$table[0].hasInitialized || notrigger ? '' : 'search' );
if (o.valueToHeader) {
// add current color to the header cell
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
} else {
// current color to span in cell
$cell.find('.currentColor').html(t);
}
return rangeSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
},
// update sticky header cell
if ($shcell.length) {
$shcell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
/**********************\
HTML5 Color picker
\**********************/
html5Color: function($cell, indx, defColor) {
var t, o = $.extend({
value : '#000000',
disabled : false,
addToggle : true,
exactMatch : true,
valueToHeader : false,
skipTest : false
}, defColor),
$input,
// Add a hidden input to hold the range values
$color = $('<input type="color" style="visibility:hidden;" value="test">').appendTo($cell),
// test if HTML5 color is supported - from Modernizr
colorSupported = o.skipTest || $color.attr('type') === 'color' && $color.val() !== 'test',
$shcell = [],
c = $cell.closest('table')[0].config,
updateColor = function(v, notrigger) {
v = ( typeof v === 'undefined' ? $input.val() : v ).toString().replace('=', '') || o.value;
var chkd = true,
t = ' (' + v + ')';
if (o.addToggle) {
$shcell.find('.toggle')[0].checked = chkd;
chkd = $cell.find('.toggle').is(':checked');
}
if ($cell.find('.colorpicker').length) {
$cell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
}
$input
.val( chkd ? v + (o.exactMatch ? '=' : '') : '' )
.trigger( !c.$table[0].hasInitialized || notrigger ? '' : 'search' );
if (o.valueToHeader) {
// add current color to the header cell
$shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
} else {
// current color to span in cell
$shcell.find('.currentColor').html(t);
$cell.find('.currentColor').html(t);
}
}
};
$color.remove();
if (colorSupported) {
t = '' + indx + Math.round(Math.random() * 100);
// add HTML5 color picker
t = '<div class="color-controls-wrapper">' +
(o.addToggle ? '<div class="button"><input id="colorbutton' + t + '" type="checkbox" class="toggle" /><label for="colorbutton' +
t + '"></label></div>' : '') +
'<input type="hidden"><input class="colorpicker" type="color" />' +
(o.valueToHeader ? '' : '<span class="currentColor">(#000000)</span>') + '</div>';
$cell.html(t);
// add span to header for the current color value - only works if the line in the updateColor() function is also un-commented out
if (o.valueToHeader) {
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.tablesorter-header-inner').append('<span class="curcolor" />');
}
$cell.find('.toggle, .colorpicker').bind('change', function(){
updateColor( $cell.find('.colorpicker').val() );
});
// hidden filter update namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
updateColor( this.value );
});
// update slider from hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
updateColor( $input.val(), true );
ts.filter.formatterUpdated($cell, indx);
});
// on reset
$cell.closest('table').bind('filterReset', function(){
// just turn off the colorpicker
if (o.addToggle) {
$cell.find('.toggle')[0].checked = false;
// update sticky header cell
if ($shcell.length) {
$shcell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
if (o.addToggle) {
$shcell.find('.toggle')[0].checked = chkd;
}
if (o.valueToHeader) {
// add current color to the header cell
$shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
} else {
// current color to span in cell
$shcell.find('.currentColor').html(t);
}
}
// delay needed because default color needs to be set in the filter
// there is no compare option here, so if addToggle = false,
// default color is #000000 (even with no value set)
setTimeout(function(){
updateColor();
}, 0);
});
};
$color.remove();
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx);
$shcell
.html(t)
.find('.toggle, .colorpicker').bind('change', function(){
updateColor( $shcell.find('.colorpicker').val() );
});
updateColor( $shcell.find('.colorpicker').val() );
});
if (colorSupported) {
t = '' + indx + Math.round(Math.random() * 100);
// add HTML5 color picker
t = '<div class="color-controls-wrapper">' +
(o.addToggle ? '<div class="button"><input id="colorbutton' + t + '" type="checkbox" class="toggle" /><label for="colorbutton' +
t + '"></label></div>' : '') +
'<input type="hidden"><input class="colorpicker" type="color" />' +
(o.valueToHeader ? '' : '<span class="currentColor">(#000000)</span>') + '</div>';
$cell.html(t);
// add span to header for the current color value - only works if the line in the updateColor() function is also un-commented out
if (o.valueToHeader) {
$cell.closest('thead').find('th[data-column=' + indx + ']').find('.tablesorter-header-inner').append('<span class="curcolor" />');
}
updateColor( o.value );
$cell.find('.toggle, .colorpicker').bind('change', function(){
updateColor( $cell.find('.colorpicker').val() );
});
// hidden filter update namespace trigger by filter widget
$input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
updateColor( this.value );
});
// update slider from hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
updateColor( $input.val(), true );
ts.filter.formatterUpdated($cell, indx);
});
// on reset
$cell.closest('table').bind('filterReset', function(){
// just turn off the colorpicker
if (o.addToggle) {
$cell.find('.toggle')[0].checked = false;
}
// delay needed because default color needs to be set in the filter
// there is no compare option here, so if addToggle = false,
// default color is #000000 (even with no value set)
setTimeout(function(){
updateColor();
}, 0);
});
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx);
$shcell
.html(t)
.find('.toggle, .colorpicker').bind('change', function(){
updateColor( $shcell.find('.colorpicker').val() );
});
updateColor( $shcell.find('.colorpicker').val() );
});
updateColor( o.value );
}
return colorSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
}
return colorSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
}
});
});
})(jQuery);

File diff suppressed because it is too large Load Diff

View File

@ -4,146 +4,146 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter || {};
ts.filterFormatter = ts.filterFormatter || {};
var ts = $.tablesorter || {};
ts.filterFormatter = ts.filterFormatter || {};
/************************\
Select2 Filter Formatter
\************************/
ts.filterFormatter.select2 = function($cell, indx, select2Def) {
var o = $.extend({
// select2 filter formatter options
cellText : '', // Text (wrapped in a label element)
match : true, // adds "filter-match" to header
value : '',
// include ANY select2 options below
multiple : true,
width : '100%'
/************************\
Select2 Filter Formatter
\************************/
ts.filterFormatter.select2 = function($cell, indx, select2Def) {
var o = $.extend({
// select2 filter formatter options
cellText : '', // Text (wrapped in a label element)
match : true, // adds 'filter-match' to header
value : '',
// include ANY select2 options below
multiple : true,
width : '100%'
}, select2Def ),
arry, data,
c = $cell.closest('table')[0].config,
wo = c.widgetOptions,
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
var val = this.value;
val = val.replace(/[/()$^]/g, '').split('|');
$cell.find('.select2').select2('val', val);
updateSelect2();
}),
$header = c.$headerIndexed[indx],
onlyAvail = $header.hasClass(wo.filter_onlyAvail),
$shcell = [],
matchPrefix = o.match ? '' : '^',
matchSuffix = o.match ? '' : '$',
}, select2Def ),
arry, data,
c = $cell.closest('table')[0].config,
wo = c.widgetOptions,
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
var val = this.value;
val = val.replace(/[/()$^]/g, '').split('|');
$cell.find('.select2').select2('val', val);
updateSelect2();
}),
$header = c.$headerIndexed[indx],
onlyAvail = $header.hasClass(wo.filter_onlyAvail),
$shcell = [],
matchPrefix = o.match ? '' : '^',
matchSuffix = o.match ? '' : '$',
// this function updates the hidden input and adds the current values to the header cell text
updateSelect2 = function() {
var arry = false,
v = $cell.find('.select2').select2('val') || o.value || '';
// convert array to string
if ($.isArray(v)) {
arry = true;
v = v.join('\u0000');
}
// escape special regex characters (http://stackoverflow.com/a/9310752/145346)
v = v.replace(/[-[\]{}()*+?.,/\\^$|#\s]/g, '\\$&');
// convert string back into an array
if (arry) {
v = v.split('\u0000');
}
$input
// add regex, so we filter exact numbers
.val( $.isArray(v) && v.length && v.join('') !== '' ? '/(' + matchPrefix + (v || []).join(matchSuffix + '|' + matchPrefix) + matchSuffix + ')/' : '' )
.trigger('search').end()
.find('.select2').select2('val', v);
// update sticky header cell
if ($shcell.length) {
$shcell.find('.select2').select2('val', v);
}
},
// this function updates the hidden input and adds the current values to the header cell text
updateSelect2 = function() {
var arry = false,
v = $cell.find('.select2').select2('val') || o.value || '';
// convert array to string
if ($.isArray(v)) {
arry = true;
v = v.join('\u0000');
}
// escape special regex characters (http://stackoverflow.com/a/9310752/145346)
v = v.replace(/[-[\]{}()*+?.,/\\^$|#\s]/g, '\\$&');
// convert string back into an array
if (arry) {
v = v.split('\u0000');
}
$input
// add regex, so we filter exact numbers
.val( $.isArray(v) && v.length && v.join('') !== '' ? '/(' + matchPrefix + (v || []).join(matchSuffix + '|' + matchPrefix) + matchSuffix + ')/' : '' )
.trigger('search').end()
.find('.select2').select2('val', v);
// update sticky header cell
if ($shcell.length) {
$shcell.find('.select2').select2('val', v);
}
},
// get options from table cell content or filter_selectSource (v2.16)
updateOptions = function(){
data = [];
arry = ts.filter.getOptionSource(c.$table[0], indx, onlyAvail) || [];
// build select2 data option
$.each(arry, function(i,v){
data.push({id: v, text: v});
});
o.data = data;
};
// get filter-match class from option
$header.toggleClass('filter-match', o.match);
if (o.cellText) {
$cell.prepend('<label>' + o.cellText + '</label>');
}
// don't add default in table options if either ajax or
// data options are already defined
if (!(o.ajax && !$.isEmptyObject(o.ajax)) && !o.data) {
updateOptions();
if (onlyAvail) {
c.$table.bind('filterEnd', function(){
updateOptions();
$cell.add($shcell).find('.select2').select2(o);
// get options from table cell content or filter_selectSource (v2.16)
updateOptions = function(){
data = [];
arry = ts.filter.getOptionSource(c.$table[0], indx, onlyAvail) || [];
// build select2 data option
$.each(arry, function(i, v){
data.push({id: v, text: v});
});
o.data = data;
};
// get filter-match class from option
$header.toggleClass('filter-match', o.match);
if (o.cellText) {
$cell.prepend('<label>' + o.cellText + '</label>');
}
}
// add a select2 hidden input!
$('<input class="select2 select2-' + indx + '" type="hidden" />')
.val(o.value)
.appendTo($cell)
.select2(o)
.bind('change', function(){
updateSelect2();
});
// don't add default in table options if either ajax or
// data options are already defined
if (!(o.ajax && !$.isEmptyObject(o.ajax)) && !o.data) {
updateOptions();
if (onlyAvail) {
c.$table.bind('filterEnd', function(){
updateOptions();
$cell.add($shcell).find('.select2').select2(o);
});
}
}
// update select2 from filter hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
// value = '/(^x$|^y$)/' => 'x,y'
var val = c.$table.data('lastSearch')[indx] || '';
val = val.replace(/^\/\(\^?/,'').replace(/\$\|\^/g, '|').replace(/\$?\)\/$/g,'').split('|');
$cell.find('.select2').select2('val', val);
updateSelect2();
ts.filter.formatterUpdated($cell, indx);
});
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
// add a select2!
$('<input class="select2 select2-' + indx + '" type="hidden">')
// add a select2 hidden input!
$('<input class="select2 select2-' + indx + '" type="hidden" />')
.val(o.value)
.appendTo($shcell)
.appendTo($cell)
.select2(o)
.bind('change', function(){
$cell.find('.select2').select2('val', $shcell.find('.select2').select2('val') );
updateSelect2();
});
if (o.cellText) {
$shcell.prepend('<label>' + o.cellText + '</label>');
}
});
// on reset
c.$table.bind('filterReset', function(){
$cell.find('.select2').select2('val', o.value || '');
setTimeout(function(){
// update select2 from filter hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function(){
// value = '/(^x$|^y$)/' => 'x,y'
var val = c.$table.data('lastSearch')[indx] || '';
val = val.replace(/^\/\(\^?/, '').replace(/\$\|\^/g, '|').replace(/\$?\)\/$/g, '').split('|');
$cell.find('.select2').select2('val', val);
updateSelect2();
}, 0);
});
ts.filter.formatterUpdated($cell, indx);
});
updateSelect2();
return $input;
};
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
$shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
// add a select2!
$('<input class="select2 select2-' + indx + '" type="hidden">')
.val(o.value)
.appendTo($shcell)
.select2(o)
.bind('change', function(){
$cell.find('.select2').select2('val', $shcell.find('.select2').select2('val') );
updateSelect2();
});
if (o.cellText) {
$shcell.prepend('<label>' + o.cellText + '</label>');
}
});
// on reset
c.$table.bind('filterReset', function(){
$cell.find('.select2').select2('val', o.value || '');
setTimeout(function(){
updateSelect2();
}, 0);
});
updateSelect2();
return $input;
};
})(jQuery);

View File

@ -1,6 +1,6 @@
/*! Widget: filter, insideRange filter type - updated 2/23/2015 (v2.21.0) */
;(function($){
'use strict';
'use strict';
// Add insideRange filter type
// ============================

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
'use strict';
'use strict';
var ts = $.tablesorter;
ts.formatter = {

View File

@ -5,246 +5,246 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
'use strict';
var ts = $.tablesorter;
ts.grouping = {
ts.grouping = {
types : {
number : function(c, $column, txt, num, group){
var value, word;
if (num > 1 && txt !== '') {
if ($column.hasClass(ts.css.sortAsc)) {
value = Math.floor(parseFloat(txt)/num) * num;
return value > parseFloat(group || 0) ? value : parseFloat(group || 0);
types : {
number : function(c, $column, txt, num, group){
var value, word;
if (num > 1 && txt !== '') {
if ($column.hasClass(ts.css.sortAsc)) {
value = Math.floor(parseFloat(txt) / num) * num;
return value > parseFloat(group || 0) ? value : parseFloat(group || 0);
} else {
value = Math.ceil(parseFloat(txt) / num) * num;
return value < parseFloat(group || num) - value ? parseFloat(group || num) - value : value;
}
} else {
value = Math.ceil(parseFloat(txt)/num) * num;
return value < parseFloat(group || num) - value ? parseFloat(group || num) - value : value;
word = (txt + '').match(/\d+/g);
return word && word.length >= num ? word[num - 1] : txt || '';
}
} else {
word = (txt + '').match(/\d+/g);
},
separator : function(c, $column, txt, num){
var word = (txt + '').split(c.widgetOptions.group_separator);
return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
},
word : function(c, $column, txt, num){
var word = (txt + ' ').match(/\w+/g);
return word && word.length >= num ? word[num - 1] : txt || '';
},
letter : function(c, $column, txt, num){
return txt ? (txt + ' ').substring(0, num) : '';
},
date : function(c, $column, txt, part, group){
var wo = c.widgetOptions,
time = new Date(txt || ''),
hours = time.getHours();
return part === 'year' ? time.getFullYear() :
part === 'month' ? wo.group_months[time.getMonth()] :
part === 'monthyear' ? wo.group_months[time.getMonth()] + ' ' + time.getFullYear() :
part === 'day' ? wo.group_months[time.getMonth()] + ' ' + time.getDate() :
part === 'week' ? wo.group_week[time.getDay()] :
part === 'time' ? ('00' + (hours > 12 ? hours - 12 : hours === 0 ? hours + 12 : hours)).slice(-2) + ':' +
('00' + time.getMinutes()).slice(-2) + ' ' + ('00' + wo.group_time[hours >= 12 ? 1 : 0]).slice(-2) :
wo.group_dateString(time);
}
},
separator : function(c, $column, txt, num){
var word = (txt + '').split(c.widgetOptions.group_separator);
return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
},
word : function(c, $column, txt, num){
var word = (txt + ' ').match(/\w+/g);
return word && word.length >= num ? word[num - 1] : txt || '';
},
letter : function(c, $column, txt, num){
return txt ? (txt + ' ').substring(0, num) : '';
},
date : function(c, $column, txt, part, group){
var wo = c.widgetOptions,
time = new Date(txt || ''),
hours = time.getHours();
return part === 'year' ? time.getFullYear() :
part === 'month' ? wo.group_months[time.getMonth()] :
part === 'monthyear' ? wo.group_months[time.getMonth()] + ' ' + time.getFullYear() :
part === 'day' ? wo.group_months[time.getMonth()] + ' ' + time.getDate() :
part === 'week' ? wo.group_week[time.getDay()] :
part === 'time' ? ('00' + (hours > 12 ? hours - 12 : hours === 0 ? hours + 12 : hours)).slice(-2) + ':' +
('00' + time.getMinutes()).slice(-2) + ' ' + ('00' + wo.group_time[hours >= 12 ? 1 : 0]).slice(-2) :
wo.group_dateString(time);
}
},
update : function(table, c, wo){
if ($.isEmptyObject(c.cache)) { return; }
var rowIndex, tbodyIndex, currentGroup, $rows, groupClass, grouping, norm_rows, saveName, direction,
lang = wo.grouping_language,
group = '',
savedGroup = false,
column = c.sortList[0] ? c.sortList[0][0] : -1;
c.$table
.find('tr.group-hidden').removeClass('group-hidden').end()
.find('tr.group-header').remove();
if (wo.group_collapsible) {
// clear pager saved spacer height (in case the rows are collapsed)
c.$table.data('pagerSavedHeight', 0);
}
if (column >= 0 && !c.$headerIndexed[column].hasClass('group-false')) {
wo.group_currentGroup = ''; // save current groups
wo.group_currentGroups = {};
update : function(table, c, wo){
if ($.isEmptyObject(c.cache)) { return; }
var rowIndex, tbodyIndex, currentGroup, $rows, groupClass, grouping, norm_rows, saveName, direction,
lang = wo.grouping_language,
group = '',
savedGroup = false,
column = c.sortList[0] ? c.sortList[0][0] : -1;
c.$table
.find('tr.group-hidden').removeClass('group-hidden').end()
.find('tr.group-header').remove();
if (wo.group_collapsible) {
// clear pager saved spacer height (in case the rows are collapsed)
c.$table.data('pagerSavedHeight', 0);
}
if (column >= 0 && !c.$headerIndexed[column].hasClass('group-false')) {
wo.group_currentGroup = ''; // save current groups
wo.group_currentGroups = {};
// group class finds "group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}"
groupClass = (c.$headerIndexed[column].attr('class') || '').match(/(group-\w+(-\w+)?)/g);
// grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
grouping = groupClass ? groupClass[0].split('-') : ['group','letter',1]; // default to letter 1
// group class finds 'group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}'
groupClass = (c.$headerIndexed[column].attr('class') || '').match(/(group-\w+(-\w+)?)/g);
// grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
grouping = groupClass ? groupClass[0].split('-') : [ 'group', 'letter', 1 ]; // default to letter 1
// save current grouping
if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
wo.group_currentGroups = ts.storage( table, 'tablesorter-groups' ) || {};
// include direction when grouping numbers > 1 (reversed direction shows different range values)
direction = (grouping[1] === 'number' && grouping[2] > 1) ? 'dir' + c.sortList[0][1] : '';
// combine column, sort direction & grouping as save key
saveName = wo.group_currentGroup = '' + column + direction + grouping.join('');
if (!wo.group_currentGroups[saveName]) {
wo.group_currentGroups[saveName] = [];
} else {
savedGroup = true;
// save current grouping
if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
wo.group_currentGroups = ts.storage( table, 'tablesorter-groups' ) || {};
// include direction when grouping numbers > 1 (reversed direction shows different range values)
direction = (grouping[1] === 'number' && grouping[2] > 1) ? 'dir' + c.sortList[0][1] : '';
// combine column, sort direction & grouping as save key
saveName = wo.group_currentGroup = '' + column + direction + grouping.join('');
if (!wo.group_currentGroups[saveName]) {
wo.group_currentGroups[saveName] = [];
} else {
savedGroup = true;
}
}
}
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++) {
norm_rows = c.cache[tbodyIndex].normalized;
group = ''; // clear grouping across tbodies
$rows = c.$tbodies.eq(tbodyIndex).children('tr').not('.' + c.cssChildRow);
for (rowIndex = 0; rowIndex < $rows.length; rowIndex++) {
if ( $rows.eq(rowIndex).is(':visible') ) {
// fixes #438
if (ts.grouping.types[grouping[1]]) {
currentGroup = norm_rows[rowIndex] ?
ts.grouping.types[grouping[1]]( c, c.$headerIndexed[column], norm_rows[rowIndex][column], /date/.test(groupClass) ?
grouping[2] : parseInt(grouping[2] || 1, 10) || 1, group, lang ) : currentGroup;
if (group !== currentGroup) {
group = currentGroup;
// show range if number > 1
if (grouping[1] === 'number' && grouping[2] > 1 && currentGroup !== '') {
currentGroup += ' - ' + (parseInt(currentGroup, 10) +
((parseInt(grouping[2],10) - 1) * (c.$headerIndexed[column].hasClass(ts.css.sortAsc) ? 1 : -1)));
}
if ($.isFunction(wo.group_formatter)) {
currentGroup = wo.group_formatter((currentGroup || '').toString(), column, table, c, wo) || currentGroup;
}
$rows.eq(rowIndex).before('<tr class="group-header ' + c.selectorRemove.slice(1) +
'" unselectable="on"' + ( c.tabIndex ? ' tabindex="0"' : '' ) + '><td colspan="' +
c.columns + '">' + (wo.group_collapsible ? '<i/>' : '') + '<span class="group-name">' +
currentGroup + '</span><span class="group-count"></span></td></tr>');
if (wo.group_saveGroups && !savedGroup && wo.group_collapsed && wo.group_collapsible) {
// all groups start collapsed
wo.group_currentGroups[wo.group_currentGroup].push(currentGroup);
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++) {
norm_rows = c.cache[tbodyIndex].normalized;
group = ''; // clear grouping across tbodies
$rows = c.$tbodies.eq(tbodyIndex).children('tr').not('.' + c.cssChildRow);
for (rowIndex = 0; rowIndex < $rows.length; rowIndex++) {
if ( $rows.eq(rowIndex).is(':visible') ) {
// fixes #438
if (ts.grouping.types[grouping[1]]) {
currentGroup = norm_rows[rowIndex] ?
ts.grouping.types[grouping[1]]( c, c.$headerIndexed[column], norm_rows[rowIndex][column], /date/.test(groupClass) ?
grouping[2] : parseInt(grouping[2] || 1, 10) || 1, group, lang ) : currentGroup;
if (group !== currentGroup) {
group = currentGroup;
// show range if number > 1
if (grouping[1] === 'number' && grouping[2] > 1 && currentGroup !== '') {
currentGroup += ' - ' + (parseInt(currentGroup, 10) +
((parseInt(grouping[2], 10) - 1) * (c.$headerIndexed[column].hasClass(ts.css.sortAsc) ? 1 : -1)));
}
if ($.isFunction(wo.group_formatter)) {
currentGroup = wo.group_formatter((currentGroup || '').toString(), column, table, c, wo) || currentGroup;
}
$rows.eq(rowIndex).before('<tr class="group-header ' + c.selectorRemove.slice(1) +
'" unselectable="on"' + ( c.tabIndex ? ' tabindex="0"' : '' ) + '><td colspan="' +
c.columns + '">' + (wo.group_collapsible ? '<i/>' : '') + '<span class="group-name">' +
currentGroup + '</span><span class="group-count"></span></td></tr>');
if (wo.group_saveGroups && !savedGroup && wo.group_collapsed && wo.group_collapsible) {
// all groups start collapsed
wo.group_currentGroups[wo.group_currentGroup].push(currentGroup);
}
}
}
}
}
}
c.$table.find('tr.group-header')
.bind('selectstart', false)
.each(function(){
var isHidden, $label, name,
$row = $(this),
$rows = $row.nextUntil('tr.group-header').filter(':visible');
if (wo.group_count || $.isFunction(wo.group_callback)) {
$label = $row.find('.group-count');
if ($label.length) {
if (wo.group_count) {
$label.html( wo.group_count.replace(/\{num\}/g, $rows.length) );
}
if ($.isFunction(wo.group_callback)) {
wo.group_callback($row.find('td'), $rows, column, table);
}
}
}
if (wo.group_saveGroups && wo.group_currentGroups.length && wo.group_currentGroups[wo.group_currentGroup].length) {
name = $row.find('.group-name').text().toLowerCase();
isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1;
$row.toggleClass('collapsed', isHidden);
$rows.toggleClass('group-hidden', isHidden);
} else if (wo.group_collapsed && wo.group_collapsible) {
$row.addClass('collapsed');
$rows.addClass('group-hidden');
}
});
c.$table.trigger(wo.group_complete);
}
c.$table.find('tr.group-header')
.bind('selectstart', false)
.each(function(){
var isHidden, $label, name,
$row = $(this),
$rows = $row.nextUntil('tr.group-header').filter(':visible');
if (wo.group_count || $.isFunction(wo.group_callback)) {
$label = $row.find('.group-count');
if ($label.length) {
if (wo.group_count) {
$label.html( wo.group_count.replace(/\{num\}/g, $rows.length) );
}
if ($.isFunction(wo.group_callback)) {
wo.group_callback($row.find('td'), $rows, column, table);
}
}
}
if (wo.group_saveGroups && wo.group_currentGroups.length && wo.group_currentGroups[wo.group_currentGroup].length) {
name = $row.find('.group-name').text().toLowerCase();
isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1;
$row.toggleClass('collapsed', isHidden);
$rows.toggleClass('group-hidden', isHidden);
} else if (wo.group_collapsed && wo.group_collapsible) {
$row.addClass('collapsed');
$rows.addClass('group-hidden');
}
});
c.$table.trigger(wo.group_complete);
}
},
},
bindEvents : function(table, c, wo){
if (wo.group_collapsible) {
wo.group_currentGroups = [];
// .on() requires jQuery 1.7+
c.$table.on('click toggleGroup keyup', 'tr.group-header', function(event){
event.stopPropagation();
// pressing enter will toggle the group
if (event.type === 'keyup' && event.which !== 13) { return; }
var isCollapsed, $groups, indx,
$this = $(this),
name = $this.find('.group-name').text().toLowerCase();
// use shift-click to toggle ALL groups
if (event.shiftKey && (event.type === 'click' || event.type ==='keyup')) {
$this.siblings('.group-header').trigger('toggleGroup');
}
$this.toggleClass('collapsed');
// nextUntil requires jQuery 1.4+
$this.nextUntil('tr.group-header').toggleClass('group-hidden', $this.hasClass('collapsed') );
// save collapsed groups
if (wo.group_saveGroups && ts.storage) {
$groups = c.$table.find('.group-header');
isCollapsed = $this.hasClass('collapsed');
if (!wo.group_currentGroups[wo.group_currentGroup]) {
wo.group_currentGroups[wo.group_currentGroup] = [];
bindEvents : function(table, c, wo){
if (wo.group_collapsible) {
wo.group_currentGroups = [];
// .on() requires jQuery 1.7+
c.$table.on('click toggleGroup keyup', 'tr.group-header', function(event){
event.stopPropagation();
// pressing enter will toggle the group
if (event.type === 'keyup' && event.which !== 13) { return; }
var isCollapsed, $groups, indx,
$this = $(this),
name = $this.find('.group-name').text().toLowerCase();
// use shift-click to toggle ALL groups
if (event.shiftKey && (event.type === 'click' || event.type === 'keyup')) {
$this.siblings('.group-header').trigger('toggleGroup');
}
if (isCollapsed && wo.group_currentGroup) {
wo.group_currentGroups[wo.group_currentGroup].push( name );
} else if (wo.group_currentGroup) {
indx = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] );
if (indx > -1) {
wo.group_currentGroups[wo.group_currentGroup].splice( indx, 1 );
$this.toggleClass('collapsed');
// nextUntil requires jQuery 1.4+
$this.nextUntil('tr.group-header').toggleClass('group-hidden', $this.hasClass('collapsed') );
// save collapsed groups
if (wo.group_saveGroups && ts.storage) {
$groups = c.$table.find('.group-header');
isCollapsed = $this.hasClass('collapsed');
if (!wo.group_currentGroups[wo.group_currentGroup]) {
wo.group_currentGroups[wo.group_currentGroup] = [];
}
if (isCollapsed && wo.group_currentGroup) {
wo.group_currentGroups[wo.group_currentGroup].push( name );
} else if (wo.group_currentGroup) {
indx = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] );
if (indx > -1) {
wo.group_currentGroups[wo.group_currentGroup].splice( indx, 1 );
}
}
ts.storage( table, 'tablesorter-groups', wo.group_currentGroups );
}
ts.storage( table, 'tablesorter-groups', wo.group_currentGroups );
}
});
}
$(wo.group_saveReset).on('click', function(){
ts.grouping.clearSavedGroups(table);
});
c.$table.on('pagerChange.tsgrouping', function(){
ts.grouping.update(table, c, wo);
});
},
clearSavedGroups: function(table){
if (table && ts.storage) {
ts.storage(table, 'tablesorter-groups', '');
ts.grouping.update(table, table.config, table.config.widgetOptions);
}
}
$(wo.group_saveReset).on('click', function(){
ts.grouping.clearSavedGroups(table);
});
c.$table.on('pagerChange.tsgrouping', function(){
};
ts.addWidget({
id: 'group',
priority: 100,
options: {
group_collapsible : true, // make the group header clickable and collapse the rows below it.
group_collapsed : false, // start with all groups collapsed
group_saveGroups : true, // remember collapsed groups
group_saveReset : null, // element to clear saved collapsed groups
group_count : ' ({num})', // if not false, the '{num}' string is replaced with the number of rows in the group
group_separator : '-', // group name separator; used when group-separator-# class is used.
group_formatter : null, // function(txt, column, table, c, wo) { return txt; }
group_callback : null, // function($cell, $rows, column, table){}, callback allowing modification of the group header labels
group_complete : 'groupingComplete', // event triggered on the table when the grouping widget has finished work
// checkbox parser text used for checked/unchecked values
group_checkbox : [ 'checked', 'unchecked' ],
// change these default date names based on your language preferences
group_months : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
group_week : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
group_time : [ 'AM', 'PM' ],
// this function is used when 'group-date' is set to create the date string
// you can just return date, date.toLocaleString(), date.toLocaleDateString() or d.toLocaleTimeString()
// reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Conversion_getter
group_dateString : function(date) { return date.toLocaleString(); }
},
init: function(table, thisWidget, c, wo){
ts.grouping.bindEvents(table, c, wo);
},
format: function(table, c, wo) {
ts.grouping.update(table, c, wo);
});
},
clearSavedGroups: function(table){
if (table && ts.storage) {
ts.storage(table, 'tablesorter-groups', '');
ts.grouping.update(table, table.config, table.config.widgetOptions);
},
remove : function(table, c, wo){
c.$table
.off('click', 'tr.group-header')
.off('pagerChange.tsgrouping')
.find('.group-hidden').removeClass('group-hidden').end()
.find('tr.group-header').remove();
}
}
};
ts.addWidget({
id: 'group',
priority: 100,
options: {
group_collapsible : true, // make the group header clickable and collapse the rows below it.
group_collapsed : false, // start with all groups collapsed
group_saveGroups : true, // remember collapsed groups
group_saveReset : null, // element to clear saved collapsed groups
group_count : ' ({num})', // if not false, the "{num}" string is replaced with the number of rows in the group
group_separator : '-', // group name separator; used when group-separator-# class is used.
group_formatter : null, // function(txt, column, table, c, wo) { return txt; }
group_callback : null, // function($cell, $rows, column, table){}, callback allowing modification of the group header labels
group_complete : 'groupingComplete', // event triggered on the table when the grouping widget has finished work
// checkbox parser text used for checked/unchecked values
group_checkbox : [ 'checked', 'unchecked' ],
// change these default date names based on your language preferences
group_months : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
group_week : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
group_time : [ 'AM', 'PM' ],
// this function is used when "group-date" is set to create the date string
// you can just return date, date.toLocaleString(), date.toLocaleDateString() or d.toLocaleTimeString()
// reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Conversion_getter
group_dateString : function(date) { return date.toLocaleString(); }
},
init: function(table, thisWidget, c, wo){
ts.grouping.bindEvents(table, c, wo);
},
format: function(table, c, wo) {
ts.grouping.update(table, c, wo);
},
remove : function(table, c, wo){
c.$table
.off('click', 'tr.group-header')
.off('pagerChange.tsgrouping')
.find('.group-hidden').removeClass('group-hidden').end()
.find('tr.group-header').remove();
}
});
});
})(jQuery);

View File

@ -5,14 +5,14 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter;
'use strict';
var ts = $.tablesorter;
ts.addWidget({
id: 'headerTitles',
options: {
// use aria-label text
// e.g. "First Name: Ascending sort applied, activate to apply a descending sort"
// e.g. 'First Name: Ascending sort applied, activate to apply a descending sort'
headerTitle_useAria : false,
// add tooltip class
headerTitle_tooltip : '',

View File

@ -5,7 +5,7 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($) {
"use strict";
'use strict';
var ts = $.tablesorter,
@ -28,10 +28,10 @@
arry = $cells.not($el).map(function(){
$t = $(this);
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
if (typeof txt === 'undefined') {
txt = this.textContent || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table) || 0;
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ''), table) || 0;
return isNaN(txt) ? 0 : txt;
}).get();
}
@ -57,15 +57,15 @@
mathAbove = $t.filter('[' + dataAttrib + '^=above]').length;
// ignore filtered rows & rows with data-math="ignore" (and starting row)
if ( ( !$rows.eq(i).hasClass(filtered) && $rows.eq(i).not('[' + dataAttrib + '=ignore]').length && i !== len ) || mathAbove && i !== len ) {
// stop calculating "above", when encountering another "above"
// stop calculating 'above', when encountering another 'above'
if (mathAbove) {
i = 0;
} else if ($t.length) {
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
if (typeof txt === 'undefined') {
txt = $t[0].textContent || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table) || 0;
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ''), table) || 0;
arry.push(isNaN(txt) ? 0 : txt);
}
}
@ -76,11 +76,11 @@
$t = $(this).children().filter('[data-column=' + cIndex + ']');
if (!$(this).hasClass(filtered) && $t.not('[' + dataAttrib + '^=above],[' + dataAttrib + '^=col]').length && !$t.is($el)) {
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
if (typeof txt === 'undefined') {
txt = ($t[0] ? $t[0].textContent : '') || $t.text();
}
// isNaN('') => false
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table) || 0;
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ''), table) || 0;
arry.push(isNaN(txt) ? 0 : txt);
}
});
@ -102,10 +102,10 @@
col = parseInt( $t.attr('data-column'), 10);
if (!$t.filter('[' + dataAttrib + ']').length && $.inArray(col, wo.math_ignore) < 0) {
txt = $t.attr(c.textAttribute);
if (typeof txt === "undefined") {
if (typeof txt === 'undefined') {
txt = ($t[0] ? $t[0].textContent : '') || $t.text();
}
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ""), table) || 0;
txt = ts.formatFloat(txt.replace(/[^\w,. \-()]/g, ''), table) || 0;
arry.push(isNaN(txt) ? 0 : txt);
}
});
@ -133,8 +133,8 @@
$mathCells = c.$table.find('.' + c.cssInfoBlock + ', tfoot').find('[' + dataAttrib + ']');
math.mathType( table, wo, $mathCells, wo.math_priority, dataAttrib );
// find the "all" total
math.mathType( table, wo, c.$table.find('[' + dataAttrib + '^=all]'), ['all'], dataAttrib );
// find the 'all' total
math.mathType( table, wo, c.$table.find('[' + dataAttrib + '^=all]'), [ 'all' ], dataAttrib );
wo.math_isUpdating = true;
c.$table.trigger('update');
@ -153,8 +153,8 @@
$cells.filter('[' + dataAttrib + '^=' + type + ']').each(function(){
$t = $(this);
formula = ($t.attr(dataAttrib) || '').replace(type + '-', '');
arry = (type === "row") ? math.getRow(table, wo, $t, dataAttrib) :
(type === "all") ? getAll : math.getColumn(table, wo, $t, type, dataAttrib);
arry = (type === 'row') ? math.getRow(table, wo, $t, dataAttrib) :
(type === 'all') ? getAll : math.getColumn(table, wo, $t, type, dataAttrib);
if (eq[formula]) {
t = eq[formula](arry);
if (table.config.debug && console && console.log) {
@ -232,7 +232,7 @@
// search for separator for grp & decimal, anything not digit, not +/- sign, not #.
result = m.match( /[^\d\-\+#]/g );
decimal = ( result && result[result.length-1] ) || '.'; // treat the right most symbol as decimal
decimal = ( result && result[result.length - 1] ) || '.'; // treat the right most symbol as decimal
group = ( result && result[1] && result[0] ) || ','; // treat the left most symbol as group separator
// split the decimal for the format string if any.
@ -282,7 +282,7 @@
v[0] = str;
}
v[1] = ( m[1] && v[1] ) ? decimal + v[1] : "";
v[1] = ( m[1] && v[1] ) ? decimal + v[1] : '';
// put back any negation, combine integer and fraction, and add back prefix & suffix
return prefix + ( ( isNegative ? '-' : '' ) + v[0] + v[1] ) + suffix;
};
@ -304,7 +304,7 @@
},
median : function(arry) {
// https://gist.github.com/caseyjustus/1166258
arry.sort( function(a,b){ return a - b; } );
arry.sort( function(a, b){ return a - b; } );
var half = Math.floor( arry.length / 2 );
return (arry.length % 2) ? arry[half] : ( arry[half - 1] + arry[half] ) / 2.0;
},
@ -314,12 +314,12 @@
var i, el,
modeMap = {},
maxCount = 1,
modes = [arry[0]];
modes = [ arry[0] ];
for (i = 0; i < arry.length; i++) {
el = arry[i];
modeMap[el] = modeMap[el] ? modeMap[el] + 1 : 1;
if ( modeMap[el] > maxCount ) {
modes = [el];
modes = [ el ];
maxCount = modeMap[el];
} else if (modeMap[el] === maxCount) {
modes.push(el);
@ -327,7 +327,7 @@
}
}
// returns arry of modes if there is a tie
return modes.sort( function(a,b){ return a - b; } );
return modes.sort( function(a, b){ return a - b; } );
},
max : function(arry) {
return Math.max.apply( Math, arry );
@ -336,7 +336,7 @@
return Math.min.apply( Math, arry );
},
range: function(arry) {
var v = arry.sort(function(a,b){ return a - b; });
var v = arry.sort(function(a, b){ return a - b; });
return v[ arry.length - 1 ] - v[0];
},
// common variance equation
@ -374,7 +374,7 @@
// add new widget called repeatHeaders
// ************************************
ts.addWidget({
id: "math",
id: 'math',
priority: 100,
options: {
math_data : 'math',
@ -384,7 +384,7 @@
math_mask : '#,##0.00',
// complete executed after each fucntion
math_complete : null, // function($cell, wo, result, value, arry){ return result; },
// order of calculation; "all" is last
// order of calculation; 'all' is last
math_priority : [ 'row', 'above', 'col' ],
// template for or just prepend the mask prefix & suffix with this HTML
// e.g. '<span class="red">{content}</span>'

View File

@ -7,365 +7,365 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter,
var ts = $.tablesorter,
output = ts.output = {
output = ts.output = {
event : 'outputTable',
event : 'outputTable',
// wrap line breaks & tabs in quotes
regexQuote : /([\n\t\x09\x0d\x0a]|<[^<]+>)/, // test if cell needs wrapping quotes
regexBR : /(<br([\s\/])?>|\n)/g, // replace
regexIMG : /<img[^>]+alt\s*=\s*['"]([^'"]+)['"][^>]*>/i, // match
regexHTML : /<[^<]+>/g, // replace
// wrap line breaks & tabs in quotes
regexQuote : /([\n\t\x09\x0d\x0a]|<[^<]+>)/, // test if cell needs wrapping quotes
regexBR : /(<br([\s\/])?>|\n)/g, // replace
regexIMG : /<img[^>]+alt\s*=\s*['"]([^'"]+)['"][^>]*>/i, // match
regexHTML : /<[^<]+>/g, // replace
replaceCR : '\x0d\x0a',
replaceTab : '\x09',
replaceCR : '\x0d\x0a',
replaceTab : '\x09',
popupTitle : 'Output',
popupStyle : 'width:100%;height:100%;', // for textarea
message : 'Your device does not support downloading. Please try again in desktop browser.',
popupTitle : 'Output',
popupStyle : 'width:100%;height:100%;', // for textarea
message : 'Your device does not support downloading. Please try again in desktop browser.',
init : function(c) {
c.$table
.off(output.event)
.on(output.event, function( e ) {
e.stopPropagation();
// explicitly use table.config.widgetOptions because we want
// the most up-to-date values; not the "wo" from initialization
output.process(c, c.widgetOptions);
});
},
init : function(c) {
c.$table
.off(output.event)
.on(output.event, function( e ) {
e.stopPropagation();
// explicitly use table.config.widgetOptions because we want
// the most up-to-date values; not the 'wo' from initialization
output.process(c, c.widgetOptions);
});
},
processRow: function(c, $rows, isHeader, isJSON) {
var $cell, $cells, cellsLen, rowIndex, row, col, indx, rowspanLen, colspanLen, txt,
wo = c.widgetOptions,
tmpRow = [],
dupe = wo.output_duplicateSpans,
addSpanIndex = isHeader && isJSON && wo.output_headerRows && $.isFunction(wo.output_callbackJSON),
cellIndex = 0,
rowsLength = $rows.length;
processRow: function(c, $rows, isHeader, isJSON) {
var $cell, $cells, cellsLen, rowIndex, row, col, indx, rowspanLen, colspanLen, txt,
wo = c.widgetOptions,
tmpRow = [],
dupe = wo.output_duplicateSpans,
addSpanIndex = isHeader && isJSON && wo.output_headerRows && $.isFunction(wo.output_callbackJSON),
cellIndex = 0,
rowsLength = $rows.length;
for ( rowIndex = 0; rowIndex < rowsLength; rowIndex++ ) {
if (!tmpRow[rowIndex]) { tmpRow[rowIndex] = []; }
cellIndex = 0;
$cells = $rows.eq( rowIndex ).children();
cellsLen = $cells.length;
for ( indx = 0; indx < cellsLen; indx++ ) {
$cell = $cells.eq( indx );
// process rowspans
if ($cell.filter('[rowspan]').length) {
rowspanLen = parseInt( $cell.attr('rowspan'), 10) - 1;
txt = output.formatData( c, wo, $cell, isHeader );
for (row = 1; row <= rowspanLen; row++) {
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
tmpRow[rowIndex + row][cellIndex] = isHeader ? txt : dupe ? txt : '';
for ( rowIndex = 0; rowIndex < rowsLength; rowIndex++ ) {
if (!tmpRow[rowIndex]) { tmpRow[rowIndex] = []; }
cellIndex = 0;
$cells = $rows.eq( rowIndex ).children();
cellsLen = $cells.length;
for ( indx = 0; indx < cellsLen; indx++ ) {
$cell = $cells.eq( indx );
// process rowspans
if ($cell.filter('[rowspan]').length) {
rowspanLen = parseInt( $cell.attr('rowspan'), 10) - 1;
txt = output.formatData( c, wo, $cell, isHeader );
for (row = 1; row <= rowspanLen; row++) {
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
tmpRow[rowIndex + row][cellIndex] = isHeader ? txt : dupe ? txt : '';
}
}
}
// process colspans
if ($cell.filter('[colspan]').length) {
colspanLen = parseInt( $cell.attr('colspan'), 10) - 1;
// allow data-attribute to be an empty string
txt = output.formatData( c, wo, $cell, isHeader );
for (col = 1; col <= colspanLen; col++) {
// if we're processing the header & making JSON, the header names need to be unique
if ($cell.filter('[rowspan]').length) {
rowspanLen = parseInt( $cell.attr('rowspan'), 10);
for (row = 0; row < rowspanLen; row++) {
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
tmpRow[rowIndex + row][cellIndex + col] = addSpanIndex ?
// process colspans
if ($cell.filter('[colspan]').length) {
colspanLen = parseInt( $cell.attr('colspan'), 10) - 1;
// allow data-attribute to be an empty string
txt = output.formatData( c, wo, $cell, isHeader );
for (col = 1; col <= colspanLen; col++) {
// if we're processing the header & making JSON, the header names need to be unique
if ($cell.filter('[rowspan]').length) {
rowspanLen = parseInt( $cell.attr('rowspan'), 10);
for (row = 0; row < rowspanLen; row++) {
if (!tmpRow[rowIndex + row]) { tmpRow[rowIndex + row] = []; }
tmpRow[rowIndex + row][cellIndex + col] = addSpanIndex ?
wo.output_callbackJSON($cell, txt, cellIndex + col) ||
txt + '(' + (cellIndex + col) + ')' : isHeader ? txt : dupe ? txt : '';
}
} else {
tmpRow[rowIndex][cellIndex + col] = addSpanIndex ?
wo.output_callbackJSON($cell, txt, cellIndex + col) ||
txt + '(' + (cellIndex + col) + ')' : isHeader ? txt : dupe ? txt : '';
}
} else {
tmpRow[rowIndex][cellIndex + col] = addSpanIndex ?
wo.output_callbackJSON($cell, txt, cellIndex + col) ||
txt + '(' + (cellIndex + col) + ')' : isHeader ? txt : dupe ? txt : '';
}
}
}
// skip column if already defined
while (typeof tmpRow[rowIndex][cellIndex] !== 'undefined') { cellIndex++; }
// skip column if already defined
while (typeof tmpRow[rowIndex][cellIndex] !== 'undefined') { cellIndex++; }
tmpRow[rowIndex][cellIndex] = tmpRow[rowIndex][cellIndex] ||
output.formatData( c, wo, $cell, isHeader );
cellIndex++;
}
}
return ts.output.removeColumns( c, wo, tmpRow );
},
// remove hidden/ignored columns
removeColumns : function( c, wo, arry ) {
var rowIndex, row, colIndex,
data = [],
len = arry.length;
for ( rowIndex = 0; rowIndex < len; rowIndex++ ) {
row = arry[ rowIndex ];
data[ rowIndex ] = [];
for ( colIndex = 0; colIndex < c.columns; colIndex++ ) {
if ( !wo.output_hiddenColumnArray[ colIndex ] ) {
data[ rowIndex ].push( row[ colIndex ] );
tmpRow[rowIndex][cellIndex] = tmpRow[rowIndex][cellIndex] ||
output.formatData( c, wo, $cell, isHeader );
cellIndex++;
}
}
}
return data;
},
return ts.output.removeColumns( c, wo, tmpRow );
},
process : function(c, wo) {
var mydata, $this, $rows, headers, csvData, len, rowsLen, tmp,
hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
indx = 0,
tmpData = (wo.output_separator || ',').toLowerCase(),
outputJSON = tmpData === 'json',
outputArray = tmpData === 'array',
separator = outputJSON || outputArray ? ',' : wo.output_separator,
saveRows = wo.output_saveRows,
$el = c.$table;
// regex to look for the set separator or HTML
wo.output_regex = new RegExp('(' + (/\\/.test(separator) ? '\\' : '' ) + separator + ')' );
// remove hidden/ignored columns
removeColumns : function( c, wo, arry ) {
var rowIndex, row, colIndex,
data = [],
len = arry.length;
for ( rowIndex = 0; rowIndex < len; rowIndex++ ) {
row = arry[ rowIndex ];
data[ rowIndex ] = [];
for ( colIndex = 0; colIndex < c.columns; colIndex++ ) {
if ( !wo.output_hiddenColumnArray[ colIndex ] ) {
data[ rowIndex ].push( row[ colIndex ] );
}
}
}
return data;
},
// make a list of hidden columns
wo.output_hiddenColumnArray = [];
for ( indx = 0; indx < c.columns; indx++ ) {
wo.output_hiddenColumnArray[ indx ] = $.inArray( indx, wo.output_ignoreColumns ) > -1 ||
c.$headerIndexed[ indx ].css( 'display' ) === 'none';
}
process : function(c, wo) {
var mydata, $this, $rows, headers, csvData, len, rowsLen, tmp,
hasStringify = window.JSON && JSON.hasOwnProperty('stringify'),
indx = 0,
tmpData = (wo.output_separator || ',').toLowerCase(),
outputJSON = tmpData === 'json',
outputArray = tmpData === 'array',
separator = outputJSON || outputArray ? ',' : wo.output_separator,
saveRows = wo.output_saveRows,
$el = c.$table;
// regex to look for the set separator or HTML
wo.output_regex = new RegExp('(' + (/\\/.test(separator) ? '\\' : '' ) + separator + ')' );
// get header cells
$this = $el.find('thead tr:visible').not('.' + (ts.css.filterRow || 'tablesorter-filter-row') );
headers = output.processRow(c, $this, true, outputJSON);
// all tbody rows
$rows = $el.children('tbody').children('tr');
// get (f)iltered, (v)isible, all rows (look for the first letter only), or jQuery filter selector
$rows = /^f/.test(saveRows) ? $rows.not('.' + (wo.filter_filteredRow || 'filtered') ) :
/^v/.test(saveRows) ? $rows.filter(':visible') :
// look for '.' (class selector), '#' (id selector),
// ':' (basic filters, e.g. ':not()') or '[' (attribute selector start)
/^[.#:\[]/.test(saveRows) ? $rows.filter(saveRows) :
// default to all rows
$rows;
// process to array of arrays
csvData = output.processRow(c, $rows);
if (wo.output_includeFooter) {
// clone, to force the tfoot rows to the end of this selection of rows
// otherwise they appear after the thead (the order in the HTML)
csvData = csvData.concat( output.processRow( c, $el.children('tfoot').children('tr:visible') ) );
}
len = headers.length;
if (outputJSON) {
tmpData = [];
rowsLen = csvData.length;
for ( indx = 0; indx < rowsLen; indx++ ) {
// multiple header rows & output_headerRows = true, pick the last row...
tmp = headers[ ( len > 1 && wo.output_headerRows ) ? indx % len : len - 1 ];
tmpData.push( output.row2Hash( tmp, csvData[ indx ] ) );
// make a list of hidden columns
wo.output_hiddenColumnArray = [];
for ( indx = 0; indx < c.columns; indx++ ) {
wo.output_hiddenColumnArray[ indx ] = $.inArray( indx, wo.output_ignoreColumns ) > -1 ||
c.$headerIndexed[ indx ].css( 'display' ) === 'none';
}
// requires JSON stringify; if it doesn't exist, the output will show [object Object],... in the output window
mydata = hasStringify ? JSON.stringify(tmpData) : tmpData;
} else {
tmp = [ headers[ ( len > 1 && wo.output_headerRows ) ? indx % len : len - 1 ] ];
tmpData = output.row2CSV(wo, wo.output_headerRows ? headers : tmp, outputArray)
.concat( output.row2CSV(wo, csvData, outputArray) );
// get header cells
$this = $el.find('thead tr:visible').not('.' + (ts.css.filterRow || 'tablesorter-filter-row') );
headers = output.processRow(c, $this, true, outputJSON);
// stringify the array; if stringify doesn't exist the array will be flattened
mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
}
// all tbody rows
$rows = $el.children('tbody').children('tr');
// callback; if true returned, continue processing
if ($.isFunction(wo.output_callback) && !wo.output_callback(c, mydata)) { return; }
// get (f)iltered, (v)isible, all rows (look for the first letter only), or jQuery filter selector
$rows = /^f/.test(saveRows) ? $rows.not('.' + (wo.filter_filteredRow || 'filtered') ) :
/^v/.test(saveRows) ? $rows.filter(':visible') :
// look for '.' (class selector), '#' (id selector),
// ':' (basic filters, e.g. ':not()') or '[' (attribute selector start)
/^[.#:\[]/.test(saveRows) ? $rows.filter(saveRows) :
// default to all rows
$rows;
if ( /p/i.test( wo.output_delivery || '' ) ) {
output.popup(mydata, wo.output_popupStyle, outputJSON || outputArray);
} else {
output.download(wo, mydata);
}
// process to array of arrays
csvData = output.processRow(c, $rows);
}, // end process
row2CSV : function(wo, tmpRow, outputArray) {
var tmp, rowIndex,
csvData = [],
rowLen = tmpRow.length;
for (rowIndex = 0; rowIndex < rowLen; rowIndex++) {
// remove any blank rows
tmp = ( tmpRow[rowIndex] || [] ).join('').replace(/\"/g,'');
if ( ( tmpRow[rowIndex] || [] ).length > 0 && tmp !== '' ) {
csvData[csvData.length] = outputArray ? tmpRow[rowIndex] : tmpRow[rowIndex].join(wo.output_separator);
if (wo.output_includeFooter) {
// clone, to force the tfoot rows to the end of this selection of rows
// otherwise they appear after the thead (the order in the HTML)
csvData = csvData.concat( output.processRow( c, $el.children('tfoot').children('tr:visible') ) );
}
}
return csvData;
},
row2Hash : function( keys, values ) {
var indx,
json = {},
len = values.length;
for ( indx = 0; indx < len; indx++ ) {
if ( indx < keys.length ) {
json[ keys[ indx ] ] = values[ indx ];
}
}
return json;
},
len = headers.length;
formatData : function(c, wo, $el, isHeader) {
var attr = $el.attr(wo.output_dataAttrib),
txt = typeof attr !== 'undefined' ? attr : $el.html(),
quotes = (wo.output_separator || ',').toLowerCase(),
separator = quotes === 'json' || quotes === 'array',
// replace " with “ if undefined
result = txt.replace(/\"/g, wo.output_replaceQuote || '\u201c');
// replace line breaks with \\n & tabs with \\t
if (!wo.output_trimSpaces) {
result = result.replace(output.regexBR, output.replaceCR).replace(/\t/g, output.replaceTab);
} else {
result = result.replace(output.regexBR, '');
}
// extract img alt text
txt = result.match(output.regexIMG);
if (!wo.output_includeHTML && txt !== null) {
result = txt[1];
}
// replace/remove html
result = wo.output_includeHTML && !isHeader ? result : result.replace(output.regexHTML, '');
result = wo.output_trimSpaces || isHeader ? $.trim(result) : result;
// JSON & array outputs don't need quotes
quotes = separator ? false : wo.output_wrapQuotes || wo.output_regex.test(result) || output.regexQuote.test(result);
result = quotes ? '"' + result + '"' : result;
if (outputJSON) {
tmpData = [];
rowsLen = csvData.length;
for ( indx = 0; indx < rowsLen; indx++ ) {
// multiple header rows & output_headerRows = true, pick the last row...
tmp = headers[ ( len > 1 && wo.output_headerRows ) ? indx % len : len - 1 ];
tmpData.push( output.row2Hash( tmp, csvData[ indx ] ) );
}
// formatting callback - added v2.22.4
if ( typeof wo.output_formatContent === 'function' ) {
return wo.output_formatContent( c, wo, {
isHeader : isHeader,
$cell : $el,
content : result
});
}
return result;
},
popup : function(data, style, wrap) {
var generator = window.open('', output.popupTitle, style);
generator.document.write(
'<html><head><title>' + output.popupTitle + '</title></head><body>' +
'<textarea wrap="' + (wrap ? 'on' : 'off') + '" style="' + output.popupStyle + '">' + data + '\n</textarea>' +
'</body></html>'
);
generator.document.close();
generator.focus();
// select all text and focus within the textarea in the popup
// $(generator.document).find('textarea').select().focus();
return true;
},
// modified from https://github.com/PixelsCommander/Download-File-JS
// & http://html5-demos.appspot.com/static/a.download.html
download : function (wo, data){
var e, blob, gotBlob,
nav = window.navigator,
link = document.createElement('a');
// iOS devices do not support downloading. We have to inform user about this.
if (/(iP)/g.test(nav.userAgent)) {
alert(output.message);
return false;
}
// test for blob support
try {
gotBlob = !!new Blob();
} catch (err) {
gotBlob = false;
}
// Use HTML5 Blob if browser supports it
if ( gotBlob ) {
window.URL = window.URL || window.webkitURL;
// prepend BOM for utf-8 encoding - see https://github.com/eligrey/FileSaver.js/blob/master/FileSaver.js#L140
blob = new Blob( [ '\ufeff', data ], { type: wo.output_encoding } );
if (nav.msSaveBlob) {
// IE 10+
nav.msSaveBlob(blob, wo.output_saveFileName);
// requires JSON stringify; if it doesn't exist, the output will show [object Object],... in the output window
mydata = hasStringify ? JSON.stringify(tmpData) : tmpData;
} else {
// all other browsers
link.href = window.URL.createObjectURL(blob);
link.download = wo.output_saveFileName;
// Dispatching click event; using $(link).trigger() won't work
if (document.createEvent) {
e = document.createEvent('MouseEvents');
// event.initMouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY,
// ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(e);
tmp = [ headers[ ( len > 1 && wo.output_headerRows ) ? indx % len : len - 1 ] ];
tmpData = output.row2CSV(wo, wo.output_headerRows ? headers : tmp, outputArray)
.concat( output.row2CSV(wo, csvData, outputArray) );
// stringify the array; if stringify doesn't exist the array will be flattened
mydata = outputArray && hasStringify ? JSON.stringify(tmpData) : tmpData.join('\n');
}
// callback; if true returned, continue processing
if ($.isFunction(wo.output_callback) && !wo.output_callback(c, mydata)) { return; }
if ( /p/i.test( wo.output_delivery || '' ) ) {
output.popup(mydata, wo.output_popupStyle, outputJSON || outputArray);
} else {
output.download(wo, mydata);
}
}, // end process
row2CSV : function(wo, tmpRow, outputArray) {
var tmp, rowIndex,
csvData = [],
rowLen = tmpRow.length;
for (rowIndex = 0; rowIndex < rowLen; rowIndex++) {
// remove any blank rows
tmp = ( tmpRow[rowIndex] || [] ).join('').replace(/\"/g, '');
if ( ( tmpRow[rowIndex] || [] ).length > 0 && tmp !== '' ) {
csvData[csvData.length] = outputArray ? tmpRow[rowIndex] : tmpRow[rowIndex].join(wo.output_separator);
}
}
return false;
return csvData;
},
row2Hash : function( keys, values ) {
var indx,
json = {},
len = values.length;
for ( indx = 0; indx < len; indx++ ) {
if ( indx < keys.length ) {
json[ keys[ indx ] ] = values[ indx ];
}
}
return json;
},
formatData : function(c, wo, $el, isHeader) {
var attr = $el.attr(wo.output_dataAttrib),
txt = typeof attr !== 'undefined' ? attr : $el.html(),
quotes = (wo.output_separator || ',').toLowerCase(),
separator = quotes === 'json' || quotes === 'array',
// replace " with “ if undefined
result = txt.replace(/\"/g, wo.output_replaceQuote || '\u201c');
// replace line breaks with \\n & tabs with \\t
if (!wo.output_trimSpaces) {
result = result.replace(output.regexBR, output.replaceCR).replace(/\t/g, output.replaceTab);
} else {
result = result.replace(output.regexBR, '');
}
// extract img alt text
txt = result.match(output.regexIMG);
if (!wo.output_includeHTML && txt !== null) {
result = txt[1];
}
// replace/remove html
result = wo.output_includeHTML && !isHeader ? result : result.replace(output.regexHTML, '');
result = wo.output_trimSpaces || isHeader ? $.trim(result) : result;
// JSON & array outputs don't need quotes
quotes = separator ? false : wo.output_wrapQuotes || wo.output_regex.test(result) || output.regexQuote.test(result);
result = quotes ? '"' + result + '"' : result;
// formatting callback - added v2.22.4
if ( typeof wo.output_formatContent === 'function' ) {
return wo.output_formatContent( c, wo, {
isHeader : isHeader,
$cell : $el,
content : result
});
}
return result;
},
popup : function(data, style, wrap) {
var generator = window.open('', output.popupTitle, style);
generator.document.write(
'<html><head><title>' + output.popupTitle + '</title></head><body>' +
'<textarea wrap="' + (wrap ? 'on' : 'off') + '" style="' + output.popupStyle + '">' + data + '\n</textarea>' +
'</body></html>'
);
generator.document.close();
generator.focus();
// select all text and focus within the textarea in the popup
// $(generator.document).find('textarea').select().focus();
return true;
},
// modified from https://github.com/PixelsCommander/Download-File-JS
// & http://html5-demos.appspot.com/static/a.download.html
download : function (wo, data){
var e, blob, gotBlob,
nav = window.navigator,
link = document.createElement('a');
// iOS devices do not support downloading. We have to inform user about this.
if (/(iP)/g.test(nav.userAgent)) {
alert(output.message);
return false;
}
// test for blob support
try {
gotBlob = !!new Blob();
} catch (err) {
gotBlob = false;
}
// Use HTML5 Blob if browser supports it
if ( gotBlob ) {
window.URL = window.URL || window.webkitURL;
// prepend BOM for utf-8 encoding - see https://github.com/eligrey/FileSaver.js/blob/master/FileSaver.js#L140
blob = new Blob( [ '\ufeff', data ], { type: wo.output_encoding } );
if (nav.msSaveBlob) {
// IE 10+
nav.msSaveBlob(blob, wo.output_saveFileName);
} else {
// all other browsers
link.href = window.URL.createObjectURL(blob);
link.download = wo.output_saveFileName;
// Dispatching click event; using $(link).trigger() won't work
if (document.createEvent) {
e = document.createEvent('MouseEvents');
// event.initMouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY,
// ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(e);
}
}
return false;
}
// fallback to force file download (whether supported by server).
// not sure if this actually works in IE9 and older...
window.open( wo.output_encoding + encodeURIComponent(data) + '?download', '_self');
return true;
},
remove : function(c) {
c.$table.off(output.event);
}
// fallback to force file download (whether supported by server).
// not sure if this actually works in IE9 and older...
window.open( wo.output_encoding + encodeURIComponent(data) + '?download' , '_self');
return true;
};
},
ts.addWidget({
id: 'output',
options: {
output_separator : ',', // set to 'json', 'array' or any separator
output_ignoreColumns : [], // columns to ignore [0, 1,... ] (zero-based index)
output_hiddenColumns : false, // include hidden columns in the output
output_includeFooter : false, // include footer rows in the output
output_dataAttrib : 'data-name', // header attrib containing modified header name
output_headerRows : false, // if true, include multiple header rows (JSON only)
output_delivery : 'popup', // popup, download
output_saveRows : 'filtered', // (a)ll, (v)isible, (f)iltered or jQuery filter selector
output_duplicateSpans: true, // duplicate output data in tbody colspan/rowspan
output_replaceQuote : '\u201c;', // left double quote
output_includeHTML : false,
output_trimSpaces : true,
output_wrapQuotes : false,
output_popupStyle : 'width=500,height=300',
output_saveFileName : 'mytable.csv',
// format $cell content callback
output_formatContent : null, // function(config, data){ return data.content; }
// callback executed when processing completes
// return true to continue download/output
// return false to stop delivery & do something else with the data
output_callback : function(config, data){ return true; },
// JSON callback executed when a colspan is encountered in the header
output_callbackJSON : function($cell, txt, cellIndex) { return txt + '(' + (cellIndex) + ')'; },
// the need to modify this for Excel no longer exists
output_encoding : 'data:application/octet-stream;charset=utf8,'
},
init: function(table, thisWidget, c) {
output.init(c);
},
remove: function(table, c){
output.remove(c);
}
remove : function(c) {
c.$table.off(output.event);
}
};
ts.addWidget({
id: "output",
options: {
output_separator : ',', // set to "json", "array" or any separator
output_ignoreColumns : [], // columns to ignore [0, 1,... ] (zero-based index)
output_hiddenColumns : false, // include hidden columns in the output
output_includeFooter : false, // include footer rows in the output
output_dataAttrib : 'data-name', // header attrib containing modified header name
output_headerRows : false, // if true, include multiple header rows (JSON only)
output_delivery : 'popup', // popup, download
output_saveRows : 'filtered', // (a)ll, (v)isible, (f)iltered or jQuery filter selector
output_duplicateSpans: true, // duplicate output data in tbody colspan/rowspan
output_replaceQuote : '\u201c;', // left double quote
output_includeHTML : false,
output_trimSpaces : true,
output_wrapQuotes : false,
output_popupStyle : 'width=500,height=300',
output_saveFileName : 'mytable.csv',
// format $cell content callback
output_formatContent : null, // function(config, data){ return data.content; }
// callback executed when processing completes
// return true to continue download/output
// return false to stop delivery & do something else with the data
output_callback : function(config, data){ return true; },
// JSON callback executed when a colspan is encountered in the header
output_callbackJSON : function($cell, txt, cellIndex) { return txt + '(' + (cellIndex) + ')'; },
// the need to modify this for Excel no longer exists
output_encoding : 'data:application/octet-stream;charset=utf8,'
},
init: function(table, thisWidget, c) {
output.init(c);
},
remove: function(table, c){
output.remove(c);
}
});
});
})(jQuery);

File diff suppressed because it is too large Load Diff

View File

@ -4,120 +4,120 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter,
var ts = $.tablesorter,
printTable = ts.printTable = {
printTable = ts.printTable = {
event : 'printTable',
basicStyle : 'table, tr, td, th { border : solid 1px black; border-collapse : collapse; } td, th { padding: 2px; }',
event : 'printTable',
basicStyle : 'table, tr, td, th { border : solid 1px black; border-collapse : collapse; } td, th { padding: 2px; }',
init : function(c) {
c.$table
.unbind(printTable.event)
.bind(printTable.event, function(){
// explicitly use table.config.widgetOptions because we want
// the most up-to-date values; not the "wo" from initialization
printTable.process(c, c.widgetOptions);
init : function(c) {
c.$table
.unbind(printTable.event)
.bind(printTable.event, function(){
// explicitly use table.config.widgetOptions because we want
// the most up-to-date values; not the 'wo' from initialization
printTable.process(c, c.widgetOptions);
});
},
process : function(c, wo) {
var $this,
$table = $('<div/>').append(c.$table.clone()),
printStyle = printTable.basicStyle + 'table { width: 100% }' +
// hide filter row
'.tablesorter-filter-row { display: none }' +
// hide sort arrows
'.tablesorter-header { background-image: none !important; }';
// replace content with data-attribute content
$table.find('[' + wo.print_dataAttrib + ']').each(function(){
$this = $(this);
$this.text( $this.attr(wo.print_dataAttrib) );
});
},
process : function(c, wo) {
var $this,
$table = $('<div/>').append(c.$table.clone()),
printStyle = printTable.basicStyle + 'table { width: 100% }' +
// hide filter row
'.tablesorter-filter-row { display: none }' +
// hide sort arrows
'.tablesorter-header { background-image: none !important; }';
// === rows ===
// Assume 'visible' means rows hidden by the pager (rows set to 'display:none')
// or hidden by a class name which is added to the wo.print_extraCSS definition
if (/a/i.test(wo.print_rows)) {
// force show of all rows
printStyle += 'tbody tr { display: table-row !important; }';
} else if (/f/i.test(wo.print_rows)) {
// add definition to show all non-filtered rows (cells hidden by the pager)
printStyle += 'tbody tr:not(.' + (wo.filter_filteredRow || 'filtered') + ') { display: table-row !important; }';
}
// replace content with data-attribute content
$table.find('[' + wo.print_dataAttrib + ']').each(function(){
$this = $(this);
$this.text( $this.attr(wo.print_dataAttrib) );
});
// === columns ===
// columnSelector -> c.selector.$style
// Assume 'visible' means hidden columns have a 'display:none' style, or a class name
// add the definition to the wo.print_extraCSS option
if (/s/i.test(wo.print_columns) && c.selector && c.widgets.indexOf('columnSelector') >= 0) {
// show selected (visible) columns; make a copy of the columnSelector widget css (not media queries)
printStyle += wo.columnSelector_mediaquery && c.selector.auto ? '' : c.selector.$style.text();
} else if (/a/i.test(wo.print_columns)) {
// force show all cells
printStyle += 'td, th { display: table-cell !important; }';
}
// === rows ===
// Assume "visible" means rows hidden by the pager (rows set to "display:none")
// or hidden by a class name which is added to the wo.print_extraCSS definition
if (/a/i.test(wo.print_rows)) {
// force show of all rows
printStyle += 'tbody tr { display: table-row !important; }';
} else if (/f/i.test(wo.print_rows)) {
// add definition to show all non-filtered rows (cells hidden by the pager)
printStyle += 'tbody tr:not(.' + (wo.filter_filteredRow || 'filtered') + ') { display: table-row !important; }';
printStyle += wo.print_extraCSS;
// callback function
if ( $.isFunction(wo.print_callback) ) {
wo.print_callback( c, $table, printStyle );
} else {
printTable.printOutput(c, $table.html(), printStyle);
}
}, // end process
printOutput : function(c, data, style) {
var wo = c.widgetOptions,
generator = window.open('', wo.print_title, 'width=500,height=300'),
t = wo.print_title || c.$table.find('caption').text() || c.$table[0].id || document.title || 'table';
generator.document.write(
'<html><head><title>' + t + '</title>' +
( wo.print_styleSheet ? '<link rel="stylesheet" href="' + wo.print_styleSheet + '">' : '' ) +
'<style>' + style + '</style>' +
'</head><body>' + data + '</body></html>'
);
generator.document.close();
generator.print();
generator.close();
return true;
},
remove : function(c) {
c.$table.off(printTable.event);
}
// === columns ===
// columnSelector -> c.selector.$style
// Assume "visible" means hidden columns have a "display:none" style, or a class name
// add the definition to the wo.print_extraCSS option
if (/s/i.test(wo.print_columns) && c.selector && c.widgets.indexOf('columnSelector') >= 0) {
// show selected (visible) columns; make a copy of the columnSelector widget css (not media queries)
printStyle += wo.columnSelector_mediaquery && c.selector.auto ? '' : c.selector.$style.text();
} else if (/a/i.test(wo.print_columns)) {
// force show all cells
printStyle += 'td, th { display: table-cell !important; }';
};
ts.addWidget({
id: 'print',
options: {
print_title : '', // this option > caption > table id > 'table'
print_dataAttrib : 'data-name', // header attrib containing modified header name
print_rows : 'filtered', // (a)ll, (v)isible or (f)iltered
print_columns : 'selected', // (a)ll or (s)elected (if columnSelector widget is added)
print_extraCSS : '', // add any extra css definitions for the popup window here
print_styleSheet : '', // add the url of your print stylesheet
// callback executed when processing completes
// to continue printing, use the following function:
// function( config, $table, printStyle ) {
// // do something to the table or printStyle string
// $.tablesorter.printTable.printOutput( config, $table.html(), printStyle );
// }
print_callback : null
},
init: function(table, thisWidget, c) {
printTable.init(c);
},
remove: function(table, c){
printTable.remove(c);
}
printStyle += wo.print_extraCSS;
// callback function
if ( $.isFunction(wo.print_callback) ) {
wo.print_callback( c, $table, printStyle );
} else {
printTable.printOutput(c, $table.html(), printStyle);
}
}, // end process
printOutput : function(c, data, style) {
var wo = c.widgetOptions,
generator = window.open('', wo.print_title, 'width=500,height=300'),
t = wo.print_title || c.$table.find('caption').text() || c.$table[0].id || document.title || 'table';
generator.document.write(
'<html><head><title>' + t + '</title>' +
( wo.print_styleSheet ? '<link rel="stylesheet" href="' + wo.print_styleSheet + '">' : '' ) +
'<style>' + style + '</style>' +
'</head><body>' + data + '</body></html>'
);
generator.document.close();
generator.print();
generator.close();
return true;
},
remove : function(c) {
c.$table.off(printTable.event);
}
};
ts.addWidget({
id: 'print',
options: {
print_title : '', // this option > caption > table id > "table"
print_dataAttrib : 'data-name', // header attrib containing modified header name
print_rows : 'filtered', // (a)ll, (v)isible or (f)iltered
print_columns : 'selected', // (a)ll or (s)elected (if columnSelector widget is added)
print_extraCSS : '', // add any extra css definitions for the popup window here
print_styleSheet : '', // add the url of your print stylesheet
// callback executed when processing completes
// to continue printing, use the following function:
// function( config, $table, printStyle ) {
// // do something to the table or printStyle string
// $.tablesorter.printTable.printOutput( config, $table.html(), printStyle );
// }
print_callback : null
},
init: function(table, thisWidget, c) {
printTable.init(c);
},
remove: function(table, c){
printTable.remove(c);
}
});
});
})(jQuery);

View File

@ -50,131 +50,130 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
'use strict';
var ts = $.tablesorter,
var ts = $.tablesorter,
tablereflow = {
// simple reflow
// add data-attribute to each cell which shows when media query is active
// this widget DOES NOT WORK on a table with multiple thead rows
init : function(table, c, wo) {
var $this,
title = wo.reflow_dataAttrib,
header = wo.reflow_headerAttrib,
headers = [];
c.$table
.addClass(wo.reflow_className)
.off('refresh.tsreflow updateComplete.tsreflow2')
// emulate jQuery Mobile refresh
// https://api.jquerymobile.com/table-reflow/#method-refresh
.on('refresh.tsreflow updateComplete.tsreflow2', function(){
tablereflow.init(table, c, wo);
tablereflow = {
// simple reflow
// add data-attribute to each cell which shows when media query is active
// this widget DOES NOT WORK on a table with multiple thead rows
init : function(table, c, wo) {
var $this,
title = wo.reflow_dataAttrib,
header = wo.reflow_headerAttrib,
headers = [];
c.$table
.addClass(wo.reflow_className)
.off('refresh.tsreflow updateComplete.tsreflow2')
// emulate jQuery Mobile refresh
// https://api.jquerymobile.com/table-reflow/#method-refresh
.on('refresh.tsreflow updateComplete.tsreflow2', function(){
tablereflow.init(table, c, wo);
});
c.$headers.each(function(){
$this = $(this);
headers.push( $.trim( $this.attr(header) || $this.text() ) );
});
c.$headers.each(function(){
$this = $(this);
headers.push( $.trim( $this.attr(header) || $this.text() ) );
});
c.$tbodies.children().each(function(){
$(this).children().each(function(i){
$(this).attr(title, headers[i]);
});
});
},
init2: function(table, c, wo) {
var $this, $tbody, i, $hdr, txt, len,
cols = c.columns,
header = wo.reflow2_headerAttrib,
headers = [];
c.$table
.addClass(wo.reflow2_className)
.off('refresh.tsreflow2 updateComplete.tsreflow2')
// emulate jQuery Mobile refresh
// https://api.jquerymobile.com/table-reflow/#method-refresh
.on('refresh.tsreflow2 updateComplete.tsreflow2', function(){
tablereflow.init2(table, c, wo);
c.$tbodies.children().each(function(){
$(this).children().each(function(i){
$(this).attr(title, headers[i]);
});
});
},
init2: function(table, c, wo) {
var $this, $tbody, i, $hdr, txt, len,
cols = c.columns,
header = wo.reflow2_headerAttrib,
headers = [];
c.$table
.addClass(wo.reflow2_className)
.off('refresh.tsreflow2 updateComplete.tsreflow2')
// emulate jQuery Mobile refresh
// https://api.jquerymobile.com/table-reflow/#method-refresh
.on('refresh.tsreflow2 updateComplete.tsreflow2', function(){
tablereflow.init2(table, c, wo);
});
// add <b> to every table cell with thead cell contents
for (i = 0; i < cols; i++) {
$hdr = c.$headers.filter('[data-column="' + i + '"]');
if ($hdr.length > 1) {
txt = [];
/*jshint loopfunc:true */
$hdr.each(function(){
// add <b> to every table cell with thead cell contents
for (i = 0; i < cols; i++) {
$hdr = c.$headers.filter('[data-column="' + i + '"]');
if ($hdr.length > 1) {
txt = [];
/*jshint loopfunc:true */
$hdr.each(function(){
$this = $(this);
if (!$this.hasClass(wo.reflow2_classIgnore)) {
txt.push( $this.attr(header) || $this.text() );
}
});
} else {
txt = [ $hdr.attr(header) || $hdr.text() ];
}
headers.push( txt );
}
// include 'remove-me' class so these additional elements are removed before updating
txt = '<b class="' + c.selectorRemove.slice(1) + ' ' + wo.reflow2_labelClass;
c.$tbodies.children().each(function(){
$tbody = ts.processTbody(table, $(this), true);
$tbody.children().each(function(j){
$this = $(this);
if (!$this.hasClass(wo.reflow2_classIgnore)) {
txt.push( $this.attr(header) || $this.text() );
len = headers[j].length;
i = len - 1;
while (i >= 0) {
$this.prepend(txt + (i === 0 && len > 1 ? ' ' + wo.reflow2_labelTop : '') + '">' + headers[j][i] + '</b>');
i--;
}
});
} else {
txt = [ $hdr.attr(header) || $hdr.text() ];
}
headers.push( txt );
}
// include "remove-me" class so these additional elements are removed before updating
txt = '<b class="' + c.selectorRemove.slice(1) + ' ' + wo.reflow2_labelClass;
c.$tbodies.children().each(function(){
$tbody = ts.processTbody(table, $(this), true);
$tbody.children().each(function(j){
$this = $(this);
len = headers[j].length;
i = len - 1;
while (i >= 0) {
$this.prepend(txt + (i === 0 && len > 1 ? ' ' + wo.reflow2_labelTop : '') + '">' + headers[j][i] + '</b>');
i--;
}
ts.processTbody(table, $tbody, false);
});
ts.processTbody(table, $tbody, false);
});
},
remove : function(table, c, wo) {
c.$table.removeClass(wo.reflow_className);
},
remove2 : function(table, c, wo) {
c.$table.removeClass(wo.reflow2_className);
}
};
},
remove : function(table, c, wo) {
c.$table.removeClass(wo.reflow_className);
},
remove2 : function(table, c, wo) {
c.$table.removeClass(wo.reflow2_className);
}
};
ts.addWidget({
id: "reflow",
options: {
// class name added to make it responsive (class name within media query)
reflow_className : 'ui-table-reflow',
// header attribute containing modified header name
reflow_headerAttrib : 'data-name',
// data attribute added to each tbody cell
reflow_dataAttrib : 'data-title'
},
init: function(table, thisWidget, c, wo) {
tablereflow.init(table, c, wo);
},
remove: function(table, c, wo){
tablereflow.remove(table, c, wo);
}
});
ts.addWidget({
id: "reflow2",
options: {
// class name added to make it responsive (class name within media query)
reflow2_className : 'ui-table-reflow',
// ignore header cell content with this class name
reflow2_classIgnore : 'ui-table-reflow-ignore',
// header attribute containing modified header name
reflow2_headerAttrib : 'data-name',
// class name applied to thead labels
reflow2_labelClass : 'ui-table-cell-label',
// class name applied to first row thead label
reflow2_labelTop : 'ui-table-cell-label-top'
},
init: function(table, thisWidget, c, wo) {
tablereflow.init2(table, c, wo);
},
remove: function(table, c, wo){
tablereflow.remove2(table, c, wo);
}
});
ts.addWidget({
id: 'reflow',
options: {
// class name added to make it responsive (class name within media query)
reflow_className : 'ui-table-reflow',
// header attribute containing modified header name
reflow_headerAttrib : 'data-name',
// data attribute added to each tbody cell
reflow_dataAttrib : 'data-title'
},
init: function(table, thisWidget, c, wo) {
tablereflow.init(table, c, wo);
},
remove: function(table, c, wo){
tablereflow.remove(table, c, wo);
}
});
ts.addWidget({
id: 'reflow2',
options: {
// class name added to make it responsive (class name within media query)
reflow2_className : 'ui-table-reflow',
// ignore header cell content with this class name
reflow2_classIgnore : 'ui-table-reflow-ignore',
// header attribute containing modified header name
reflow2_headerAttrib : 'data-name',
// class name applied to thead labels
reflow2_labelClass : 'ui-table-cell-label',
// class name applied to first row thead label
reflow2_labelTop : 'ui-table-cell-label-top'
},
init: function(table, thisWidget, c, wo) {
tablereflow.init2(table, c, wo);
},
remove: function(table, c, wo){
tablereflow.remove2(table, c, wo);
}
});
})(jQuery);

View File

@ -1,393 +1,394 @@
/*! Widget: resizable - updated 6/26/2015 (v2.22.2) */
/*jshint browser:true, jquery:true, unused:false */
;(function ($, window) {
'use strict';
var ts = $.tablesorter || {};
'use strict';
var ts = $.tablesorter || {};
$.extend(ts.css, {
resizableContainer : 'tablesorter-resizable-container',
resizableHandle : 'tablesorter-resizable-handle',
resizableNoSelect : 'tablesorter-disableSelection',
resizableStorage : 'tablesorter-resizable'
});
$.extend(ts.css, {
resizableContainer : 'tablesorter-resizable-container',
resizableHandle : 'tablesorter-resizable-handle',
resizableNoSelect : 'tablesorter-disableSelection',
resizableStorage : 'tablesorter-resizable'
});
// Add extra scroller css
$(function(){
var s = '<style>' +
'body.' + ts.css.resizableNoSelect + ' { -ms-user-select: none; -moz-user-select: -moz-none;' +
'-khtml-user-select: none; -webkit-user-select: none; user-select: none; }' +
'.' + ts.css.resizableContainer + ' { position: relative; height: 1px; }' +
// make handle z-index > than stickyHeader z-index, so the handle stays above sticky header
'.' + ts.css.resizableHandle + ' { position: absolute; display: inline-block; width: 8px;' +
'top: 1px; cursor: ew-resize; z-index: 3; user-select: none; -moz-user-select: none; }' +
'</style>';
$(s).appendTo('body');
});
// Add extra scroller css
$(function(){
var s = '<style>' +
'body.' + ts.css.resizableNoSelect + ' { -ms-user-select: none; -moz-user-select: -moz-none;' +
'-khtml-user-select: none; -webkit-user-select: none; user-select: none; }' +
'.' + ts.css.resizableContainer + ' { position: relative; height: 1px; }' +
// make handle z-index > than stickyHeader z-index, so the handle stays above sticky header
'.' + ts.css.resizableHandle + ' { position: absolute; display: inline-block; width: 8px;' +
'top: 1px; cursor: ew-resize; z-index: 3; user-select: none; -moz-user-select: none; }' +
'</style>';
$(s).appendTo('body');
});
ts.resizable = {
init : function( c, wo ) {
if ( c.$table.hasClass( 'hasResizable' ) ) { return; }
c.$table.addClass( 'hasResizable' );
ts.resizable = {
init : function( c, wo ) {
if ( c.$table.hasClass( 'hasResizable' ) ) { return; }
c.$table.addClass( 'hasResizable' );
var noResize, $header, column, storedSizes, tmp,
$table = c.$table,
$parent = $table.parent(),
marginTop = parseInt( $table.css( 'margin-top' ), 10 ),
var noResize, $header, column, storedSizes, tmp,
$table = c.$table,
$parent = $table.parent(),
marginTop = parseInt( $table.css( 'margin-top' ), 10 ),
// internal variables
vars = wo.resizable_ = {
useStorage : ts.storage && wo.resizable !== false,
$wrap : $parent,
mouseXPosition : 0,
$target : null,
$next : null,
overflow : $parent.css('overflow') === 'auto' ||
$parent.css('overflow') === 'scroll' ||
$parent.css('overflow-x') === 'auto' ||
$parent.css('overflow-x') === 'scroll',
storedSizes : []
};
// internal variables
vars = wo.resizable_vars = {
useStorage : ts.storage && wo.resizable !== false,
$wrap : $parent,
mouseXPosition : 0,
$target : null,
$next : null,
overflow : $parent.css('overflow') === 'auto' ||
$parent.css('overflow') === 'scroll' ||
$parent.css('overflow-x') === 'auto' ||
$parent.css('overflow-x') === 'scroll',
storedSizes : []
};
// set default widths
ts.resizableReset( c.table, true );
// set default widths
ts.resizableReset( c.table, true );
// now get measurements!
vars.tableWidth = $table.width();
// attempt to autodetect
vars.fullWidth = Math.abs( $parent.width() - vars.tableWidth ) < 20;
// now get measurements!
vars.tableWidth = $table.width();
// attempt to autodetect
vars.fullWidth = Math.abs( $parent.width() - vars.tableWidth ) < 20;
/*
// Hacky method to determine if table width is set to "auto"
// http://stackoverflow.com/a/20892048/145346
if ( !vars.fullWidth ) {
tmp = $table.width();
$header = $table.wrap('<span>').parent(); // temp variable
storedSizes = parseInt( $table.css( 'margin-left' ), 10 ) || 0;
$table.css( 'margin-left', storedSizes + 50 );
vars.tableWidth = $header.width() > tmp ? 'auto' : tmp;
$table.css( 'margin-left', storedSizes ? storedSizes : '' );
$header = null;
$table.unwrap('<span>');
}
*/
if ( vars.useStorage && vars.overflow ) {
// save table width
ts.storage( c.table, 'tablesorter-table-original-css-width', vars.tableWidth );
tmp = ts.storage( c.table, 'tablesorter-table-resized-width' ) || 'auto';
ts.resizable.setWidth( $table, tmp, true );
}
wo.resizable_.storedSizes = storedSizes = ( vars.useStorage ?
ts.storage( c.table, ts.css.resizableStorage ) :
[] ) || [];
ts.resizable.setWidths( c, wo, storedSizes );
ts.resizable.updateStoredSizes( c, wo );
wo.$resizable_container = $( '<div class="' + ts.css.resizableContainer + '">' )
.css({ top : marginTop })
.insertBefore( $table );
// add container
for ( column = 0; column < c.columns; column++ ) {
$header = c.$headerIndexed[ column ];
tmp = ts.getColumnData( c.table, c.headers, column );
noResize = ts.getData( $header, tmp, 'resizable' ) === 'false';
if ( !noResize ) {
$( '<div class="' + ts.css.resizableHandle + '">' )
.appendTo( wo.$resizable_container )
.attr({
'data-column' : column,
'unselectable' : 'on'
})
.data( 'header', $header )
.bind( 'selectstart', false );
/*
// Hacky method to determine if table width is set to 'auto'
// http://stackoverflow.com/a/20892048/145346
if ( !vars.fullWidth ) {
tmp = $table.width();
$header = $table.wrap('<span>').parent(); // temp variable
storedSizes = parseInt( $table.css( 'margin-left' ), 10 ) || 0;
$table.css( 'margin-left', storedSizes + 50 );
vars.tableWidth = $header.width() > tmp ? 'auto' : tmp;
$table.css( 'margin-left', storedSizes ? storedSizes : '' );
$header = null;
$table.unwrap('<span>');
}
}
$table.one('tablesorter-initialized', function() {
ts.resizable.setHandlePosition( c, wo );
ts.resizable.bindings( this.config, this.config.widgetOptions );
});
},
*/
updateStoredSizes : function( c, wo ) {
var column, $header,
len = c.columns,
vars = wo.resizable_;
vars.storedSizes = [];
for ( column = 0; column < len; column++ ) {
$header = c.$headerIndexed[ column ];
vars.storedSizes[ column ] = $header.is(':visible') ? $header.width() : 0;
}
},
if ( vars.useStorage && vars.overflow ) {
// save table width
ts.storage( c.table, 'tablesorter-table-original-css-width', vars.tableWidth );
tmp = ts.storage( c.table, 'tablesorter-table-resized-width' ) || 'auto';
ts.resizable.setWidth( $table, tmp, true );
}
wo.resizable_vars.storedSizes = storedSizes = ( vars.useStorage ?
ts.storage( c.table, ts.css.resizableStorage ) :
[] ) || [];
ts.resizable.setWidths( c, wo, storedSizes );
ts.resizable.updateStoredSizes( c, wo );
setWidth : function( $el, width, overflow ) {
// overflow tables need min & max width set as well
$el.css({
'width' : width,
'min-width' : overflow ? width : '',
'max-width' : overflow ? width : ''
});
},
setWidths : function( c, wo, storedSizes ) {
var column, $temp,
vars = wo.resizable_,
$extra = $( c.namespace + '_extra_headers' ),
$col = c.$table.children( 'colgroup' ).children( 'col' );
storedSizes = storedSizes || vars.storedSizes || [];
// process only if table ID or url match
if ( storedSizes.length ) {
wo.$resizable_container = $( '<div class="' + ts.css.resizableContainer + '">' )
.css({ top : marginTop })
.insertBefore( $table );
// add container
for ( column = 0; column < c.columns; column++ ) {
// set saved resizable widths
ts.resizable.setWidth( c.$headerIndexed[ column ], storedSizes[ column ], vars.overflow );
if ( $extra.length ) {
// stickyHeaders needs to modify min & max width as well
$temp = $extra.eq( column ).add( $col.eq( column ) );
ts.resizable.setWidth( $temp, storedSizes[ column ], vars.overflow );
$header = c.$headerIndexed[ column ];
tmp = ts.getColumnData( c.table, c.headers, column );
noResize = ts.getData( $header, tmp, 'resizable' ) === 'false';
if ( !noResize ) {
$( '<div class="' + ts.css.resizableHandle + '">' )
.appendTo( wo.$resizable_container )
.attr({
'data-column' : column,
'unselectable' : 'on'
})
.data( 'header', $header )
.bind( 'selectstart', false );
}
}
$temp = $( c.namespace + '_extra_table' );
if ( $temp.length && !ts.hasWidget( c.table, 'scroller' ) ) {
ts.resizable.setWidth( $temp, c.$table.outerWidth(), vars.overflow );
}
}
},
setHandlePosition : function( c, wo ) {
var startPosition,
hasScroller = ts.hasWidget( c.table, 'scroller' ),
tableHeight = c.$table.height(),
$handles = wo.$resizable_container.children(),
handleCenter = Math.floor( $handles.width() / 2 );
if ( hasScroller ) {
tableHeight = 0;
c.$table.closest( '.' + ts.css.scrollerWrap ).children().each(function(){
var $this = $(this);
// center table has a max-height set
tableHeight += $this.filter('[style*="height"]').length ? $this.height() : $this.children('table').height();
$table.one('tablesorter-initialized', function() {
ts.resizable.setHandlePosition( c, wo );
ts.resizable.bindings( this.config, this.config.widgetOptions );
});
}
// subtract out table left position from resizable handles. Fixes #864
startPosition = c.$table.position().left;
$handles.each( function() {
var $this = $(this),
column = parseInt( $this.attr( 'data-column' ), 10 ),
columns = c.columns - 1,
$header = $this.data( 'header' );
if ( !$header ) { return; } // see #859
if ( !$header.is(':visible') ) {
$this.hide();
} else if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
$this.css({
display: 'inline-block',
height : tableHeight,
left : $header.position().left - startPosition + $header.outerWidth() - handleCenter
},
updateStoredSizes : function( c, wo ) {
var column, $header,
len = c.columns,
vars = wo.resizable_vars;
vars.storedSizes = [];
for ( column = 0; column < len; column++ ) {
$header = c.$headerIndexed[ column ];
vars.storedSizes[ column ] = $header.is(':visible') ? $header.width() : 0;
}
},
setWidth : function( $el, width, overflow ) {
// overflow tables need min & max width set as well
$el.css({
'width' : width,
'min-width' : overflow ? width : '',
'max-width' : overflow ? width : ''
});
},
setWidths : function( c, wo, storedSizes ) {
var column, $temp,
vars = wo.resizable_vars,
$extra = $( c.namespace + '_extra_headers' ),
$col = c.$table.children( 'colgroup' ).children( 'col' );
storedSizes = storedSizes || vars.storedSizes || [];
// process only if table ID or url match
if ( storedSizes.length ) {
for ( column = 0; column < c.columns; column++ ) {
// set saved resizable widths
ts.resizable.setWidth( c.$headerIndexed[ column ], storedSizes[ column ], vars.overflow );
if ( $extra.length ) {
// stickyHeaders needs to modify min & max width as well
$temp = $extra.eq( column ).add( $col.eq( column ) );
ts.resizable.setWidth( $temp, storedSizes[ column ], vars.overflow );
}
}
$temp = $( c.namespace + '_extra_table' );
if ( $temp.length && !ts.hasWidget( c.table, 'scroller' ) ) {
ts.resizable.setWidth( $temp, c.$table.outerWidth(), vars.overflow );
}
}
},
setHandlePosition : function( c, wo ) {
var startPosition,
hasScroller = ts.hasWidget( c.table, 'scroller' ),
tableHeight = c.$table.height(),
$handles = wo.$resizable_container.children(),
handleCenter = Math.floor( $handles.width() / 2 );
if ( hasScroller ) {
tableHeight = 0;
c.$table.closest( '.' + ts.css.scrollerWrap ).children().each(function(){
var $this = $(this);
// center table has a max-height set
tableHeight += $this.filter('[style*="height"]').length ? $this.height() : $this.children('table').height();
});
}
});
},
// prevent text selection while dragging resize bar
toggleTextSelection : function( c, toggle ) {
var namespace = c.namespace + 'tsresize';
c.widgetOptions.resizable_.disabled = toggle;
$( 'body' ).toggleClass( ts.css.resizableNoSelect, toggle );
if ( toggle ) {
$( 'body' )
.attr( 'unselectable', 'on' )
.bind( 'selectstart' + namespace, false );
} else {
$( 'body' )
.removeAttr( 'unselectable' )
.unbind( 'selectstart' + namespace );
}
},
bindings : function( c, wo ) {
var namespace = c.namespace + 'tsresize';
wo.$resizable_container.children().bind( 'mousedown', function( event ) {
// save header cell and mouse position
var column,
vars = wo.resizable_,
$extras = $( c.namespace + '_extra_headers' ),
$header = $( event.target ).data( 'header' );
column = parseInt( $header.attr( 'data-column' ), 10 );
vars.$target = $header = $header.add( $extras.filter('[data-column="' + column + '"]') );
vars.target = column;
// if table is not as wide as it's parent, then resize the table
vars.$next = event.shiftKey || wo.resizable_targetLast ?
$header.parent().children().not( '.resizable-false' ).filter( ':last' ) :
$header.nextAll( ':not(.resizable-false)' ).eq( 0 );
column = parseInt( vars.$next.attr( 'data-column' ), 10 );
vars.$next = vars.$next.add( $extras.filter('[data-column="' + column + '"]') );
vars.next = column;
vars.mouseXPosition = event.pageX;
ts.resizable.updateStoredSizes( c, wo );
ts.resizable.toggleTextSelection( c, true );
});
$( document )
.bind( 'mousemove' + namespace, function( event ) {
var vars = wo.resizable_;
// ignore mousemove if no mousedown
if ( !vars.disabled || vars.mouseXPosition === 0 || !vars.$target ) { return; }
if ( wo.resizable_throttle ) {
clearTimeout( vars.timer );
vars.timer = setTimeout( function() {
ts.resizable.mouseMove( c, wo, event );
}, isNaN( wo.resizable_throttle ) ? 5 : wo.resizable_throttle );
} else {
ts.resizable.mouseMove( c, wo, event );
// subtract out table left position from resizable handles. Fixes #864
startPosition = c.$table.position().left;
$handles.each( function() {
var $this = $(this),
column = parseInt( $this.attr( 'data-column' ), 10 ),
columns = c.columns - 1,
$header = $this.data( 'header' );
if ( !$header ) { return; } // see #859
if ( !$header.is(':visible') ) {
$this.hide();
} else if ( column < columns || column === columns && wo.resizable_addLastColumn ) {
$this.css({
display: 'inline-block',
height : tableHeight,
left : $header.position().left - startPosition + $header.outerWidth() - handleCenter
});
}
})
.bind( 'mouseup' + namespace, function() {
if (!wo.resizable_.disabled) { return; }
ts.resizable.toggleTextSelection( c, false );
ts.resizable.stopResize( c, wo );
ts.resizable.setHandlePosition( c, wo );
});
},
// resizeEnd event triggered by scroller widget
$( window ).bind( 'resize' + namespace + ' resizeEnd' + namespace, function() {
ts.resizable.setHandlePosition( c, wo );
});
// right click to reset columns to default widths
c.$table
.bind( 'columnUpdate' + namespace, function() {
ts.resizable.setHandlePosition( c, wo );
})
.find( 'thead:first' )
.add( $( c.namespace + '_extra_table' ).find( 'thead:first' ) )
.bind( 'contextmenu' + namespace, function() {
// $.isEmptyObject() needs jQuery 1.4+; allow right click if already reset
var allowClick = wo.resizable_.storedSizes.length === 0;
ts.resizableReset( c.table );
ts.resizable.setHandlePosition( c, wo );
wo.resizable_.storedSizes = [];
return allowClick;
});
},
mouseMove : function( c, wo, event ) {
if ( wo.resizable_.mouseXPosition === 0 || !wo.resizable_.$target ) { return; }
// resize columns
var column,
total = 0,
vars = wo.resizable_,
$next = vars.$next,
tar = vars.storedSizes[ vars.target ],
leftEdge = event.pageX - vars.mouseXPosition;
if ( vars.overflow ) {
if ( tar + leftEdge > 0 ) {
vars.storedSizes[ vars.target ] += leftEdge;
ts.resizable.setWidth( vars.$target, vars.storedSizes[ vars.target ], true );
// update the entire table width
for ( column = 0; column < c.columns; column++ ) {
total += vars.storedSizes[ column ];
}
ts.resizable.setWidth( c.$table.add( $( c.namespace + '_extra_table' ) ), total );
}
if ( !$next.length ) {
// if expanding right-most column, scroll the wrapper
vars.$wrap[0].scrollLeft = c.$table.width();
}
} else if ( vars.fullWidth ) {
vars.storedSizes[ vars.target ] += leftEdge;
vars.storedSizes[ vars.next ] -= leftEdge;
ts.resizable.setWidths( c, wo );
} else {
vars.storedSizes[ vars.target ] += leftEdge;
ts.resizable.setWidths( c, wo );
}
vars.mouseXPosition = event.pageX;
// dynamically update sticky header widths
c.$table.trigger('stickyHeadersUpdate');
},
stopResize : function( c, wo ) {
var vars = wo.resizable_;
ts.resizable.updateStoredSizes( c, wo );
if ( vars.useStorage ) {
// save all column widths
ts.storage( c.table, ts.css.resizableStorage, vars.storedSizes );
ts.storage( c.table, 'tablesorter-table-resized-width', c.$table.width() );
}
vars.mouseXPosition = 0;
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.trigger('stickyHeadersUpdate');
}
};
// this widget saves the column widths if
// $.tablesorter.storage function is included
// **************************
ts.addWidget({
id: "resizable",
priority: 40,
options: {
resizable : true, // save column widths to storage
resizable_addLastColumn : false,
resizable_widths : [],
resizable_throttle : false, // set to true (5ms) or any number 0-10 range
resizable_targetLast : false,
resizable_fullWidth : null
},
init: function(table, thisWidget, c, wo) {
ts.resizable.init( c, wo );
},
remove: function( table, c, wo, refreshing ) {
if (wo.$resizable_container) {
// prevent text selection while dragging resize bar
toggleTextSelection : function( c, toggle ) {
var namespace = c.namespace + 'tsresize';
c.$table.add( $( c.namespace + '_extra_table' ) )
.removeClass('hasResizable')
.children( 'thead' ).unbind( 'contextmenu' + namespace );
c.widgetOptions.resizable_vars.disabled = toggle;
$( 'body' ).toggleClass( ts.css.resizableNoSelect, toggle );
if ( toggle ) {
$( 'body' )
.attr( 'unselectable', 'on' )
.bind( 'selectstart' + namespace, false );
} else {
$( 'body' )
.removeAttr( 'unselectable' )
.unbind( 'selectstart' + namespace );
}
},
bindings : function( c, wo ) {
var namespace = c.namespace + 'tsresize';
wo.$resizable_container.children().bind( 'mousedown', function( event ) {
// save header cell and mouse position
var column,
vars = wo.resizable_vars,
$extras = $( c.namespace + '_extra_headers' ),
$header = $( event.target ).data( 'header' );
column = parseInt( $header.attr( 'data-column' ), 10 );
vars.$target = $header = $header.add( $extras.filter('[data-column="' + column + '"]') );
vars.target = column;
// if table is not as wide as it's parent, then resize the table
vars.$next = event.shiftKey || wo.resizable_targetLast ?
$header.parent().children().not( '.resizable-false' ).filter( ':last' ) :
$header.nextAll( ':not(.resizable-false)' ).eq( 0 );
column = parseInt( vars.$next.attr( 'data-column' ), 10 );
vars.$next = vars.$next.add( $extras.filter('[data-column="' + column + '"]') );
vars.next = column;
vars.mouseXPosition = event.pageX;
ts.resizable.updateStoredSizes( c, wo );
ts.resizable.toggleTextSelection( c, true );
});
$( document )
.bind( 'mousemove' + namespace, function( event ) {
var vars = wo.resizable_vars;
// ignore mousemove if no mousedown
if ( !vars.disabled || vars.mouseXPosition === 0 || !vars.$target ) { return; }
if ( wo.resizable_throttle ) {
clearTimeout( vars.timer );
vars.timer = setTimeout( function() {
ts.resizable.mouseMove( c, wo, event );
}, isNaN( wo.resizable_throttle ) ? 5 : wo.resizable_throttle );
} else {
ts.resizable.mouseMove( c, wo, event );
}
})
.bind( 'mouseup' + namespace, function() {
if (!wo.resizable_vars.disabled) { return; }
ts.resizable.toggleTextSelection( c, false );
ts.resizable.stopResize( c, wo );
ts.resizable.setHandlePosition( c, wo );
});
// resizeEnd event triggered by scroller widget
$( window ).bind( 'resize' + namespace + ' resizeEnd' + namespace, function() {
ts.resizable.setHandlePosition( c, wo );
});
// right click to reset columns to default widths
c.$table
.bind( 'columnUpdate' + namespace, function() {
ts.resizable.setHandlePosition( c, wo );
})
.find( 'thead:first' )
.add( $( c.namespace + '_extra_table' ).find( 'thead:first' ) )
.bind( 'contextmenu' + namespace, function() {
// $.isEmptyObject() needs jQuery 1.4+; allow right click if already reset
var allowClick = wo.resizable_vars.storedSizes.length === 0;
ts.resizableReset( c.table );
ts.resizable.setHandlePosition( c, wo );
wo.resizable_vars.storedSizes = [];
return allowClick;
});
},
mouseMove : function( c, wo, event ) {
if ( wo.resizable_vars.mouseXPosition === 0 || !wo.resizable_vars.$target ) { return; }
// resize columns
var column,
total = 0,
vars = wo.resizable_vars,
$next = vars.$next,
tar = vars.storedSizes[ vars.target ],
leftEdge = event.pageX - vars.mouseXPosition;
if ( vars.overflow ) {
if ( tar + leftEdge > 0 ) {
vars.storedSizes[ vars.target ] += leftEdge;
ts.resizable.setWidth( vars.$target, vars.storedSizes[ vars.target ], true );
// update the entire table width
for ( column = 0; column < c.columns; column++ ) {
total += vars.storedSizes[ column ];
}
ts.resizable.setWidth( c.$table.add( $( c.namespace + '_extra_table' ) ), total );
}
if ( !$next.length ) {
// if expanding right-most column, scroll the wrapper
vars.$wrap[0].scrollLeft = c.$table.width();
}
} else if ( vars.fullWidth ) {
vars.storedSizes[ vars.target ] += leftEdge;
vars.storedSizes[ vars.next ] -= leftEdge;
ts.resizable.setWidths( c, wo );
} else {
vars.storedSizes[ vars.target ] += leftEdge;
ts.resizable.setWidths( c, wo );
}
vars.mouseXPosition = event.pageX;
// dynamically update sticky header widths
c.$table.trigger('stickyHeadersUpdate');
},
stopResize : function( c, wo ) {
var vars = wo.resizable_vars;
ts.resizable.updateStoredSizes( c, wo );
if ( vars.useStorage ) {
// save all column widths
ts.storage( c.table, ts.css.resizableStorage, vars.storedSizes );
ts.storage( c.table, 'tablesorter-table-resized-width', c.$table.width() );
}
vars.mouseXPosition = 0;
vars.$target = vars.$next = null;
// will update stickyHeaders, just in case, see #912
c.$table.trigger('stickyHeadersUpdate');
}
};
// this widget saves the column widths if
// $.tablesorter.storage function is included
// **************************
ts.addWidget({
id: 'resizable',
priority: 40,
options: {
resizable : true, // save column widths to storage
resizable_addLastColumn : false,
resizable_widths : [],
resizable_throttle : false, // set to true (5ms) or any number 0-10 range
resizable_targetLast : false,
resizable_fullWidth : null
},
init: function(table, thisWidget, c, wo) {
ts.resizable.init( c, wo );
},
remove: function( table, c, wo, refreshing ) {
if (wo.$resizable_container) {
var namespace = c.namespace + 'tsresize';
c.$table.add( $( c.namespace + '_extra_table' ) )
.removeClass('hasResizable')
.children( 'thead' )
.unbind( 'contextmenu' + namespace );
wo.$resizable_container.remove();
ts.resizable.toggleTextSelection( c, false );
ts.resizableReset( table, refreshing );
$( document ).unbind( 'mousemove' + namespace + ' mouseup' + namespace );
}
}
});
ts.resizableReset = function( table, refreshing ) {
$( table ).each(function(){
var index, $t,
c = this.config,
wo = c && c.widgetOptions,
vars = wo.resizable_;
if ( table && c && c.$headerIndexed.length ) {
// restore the initial table width
if ( vars.overflow && vars.tableWidth ) {
ts.resizable.setWidth( c.$table, vars.tableWidth, true );
if ( vars.useStorage ) {
ts.storage( table, 'tablesorter-table-resized-width', 'auto' );
}
}
for ( index = 0; index < c.columns; index++ ) {
$t = c.$headerIndexed[ index ];
if ( wo.resizable_widths && wo.resizable_widths[ index ] ) {
ts.resizable.setWidth( $t, wo.resizable_widths[ index ], vars.overflow );
} else if ( !$t.hasClass( 'resizable-false' ) ) {
// don't clear the width of any column that is not resizable
ts.resizable.setWidth( $t, '', vars.overflow );
}
}
// reset stickyHeader widths
c.$table.trigger( 'stickyHeadersUpdate' );
if ( ts.storage && !refreshing ) {
ts.storage( this, ts.css.resizableStorage, {} );
ts.resizable.toggleTextSelection( c, false );
ts.resizableReset( table, refreshing );
$( document ).unbind( 'mousemove' + namespace + ' mouseup' + namespace );
}
}
});
};
ts.resizableReset = function( table, refreshing ) {
$( table ).each(function(){
var index, $t,
c = this.config,
wo = c && c.widgetOptions,
vars = wo.resizable_vars;
if ( table && c && c.$headerIndexed.length ) {
// restore the initial table width
if ( vars.overflow && vars.tableWidth ) {
ts.resizable.setWidth( c.$table, vars.tableWidth, true );
if ( vars.useStorage ) {
ts.storage( table, 'tablesorter-table-resized-width', 'auto' );
}
}
for ( index = 0; index < c.columns; index++ ) {
$t = c.$headerIndexed[ index ];
if ( wo.resizable_widths && wo.resizable_widths[ index ] ) {
ts.resizable.setWidth( $t, wo.resizable_widths[ index ], vars.overflow );
} else if ( !$t.hasClass( 'resizable-false' ) ) {
// don't clear the width of any column that is not resizable
ts.resizable.setWidth( $t, '', vars.overflow );
}
}
// reset stickyHeader widths
c.$table.trigger( 'stickyHeadersUpdate' );
if ( ts.storage && !refreshing ) {
ts.storage( this, ts.css.resizableStorage, {} );
}
}
});
};
})( jQuery, window );

View File

@ -1,68 +1,68 @@
/*! Widget: saveSort */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
'use strict';
var ts = $.tablesorter || {};
// this widget saves the last sort only if the
// saveSort widget option is true AND the
// $.tablesorter.storage function is included
// **************************
ts.addWidget({
id: 'saveSort',
priority: 20,
options: {
saveSort : true
},
init: function(table, thisWidget, c, wo) {
// run widget format before all other widgets are applied to the table
thisWidget.format(table, c, wo, true);
},
format: function(table, c, wo, init) {
var stored, time,
$table = c.$table,
saveSort = wo.saveSort !== false, // make saveSort active/inactive; default to true
sortList = { "sortList" : c.sortList };
if (c.debug) {
time = new Date();
}
if ($table.hasClass('hasSaveSort')) {
if (saveSort && table.hasInitialized && ts.storage) {
ts.storage( table, 'tablesorter-savesort', sortList );
if (c.debug) {
ts.benchmark('saveSort widget: Saving last sort: ' + c.sortList, time);
// this widget saves the last sort only if the
// saveSort widget option is true AND the
// $.tablesorter.storage function is included
// **************************
ts.addWidget({
id: 'saveSort',
priority: 20,
options: {
saveSort : true
},
init: function(table, thisWidget, c, wo) {
// run widget format before all other widgets are applied to the table
thisWidget.format(table, c, wo, true);
},
format: function(table, c, wo, init) {
var stored, time,
$table = c.$table,
saveSort = wo.saveSort !== false, // make saveSort active/inactive; default to true
sortList = { 'sortList' : c.sortList };
if (c.debug) {
time = new Date();
}
if ($table.hasClass('hasSaveSort')) {
if (saveSort && table.hasInitialized && ts.storage) {
ts.storage( table, 'tablesorter-savesort', sortList );
if (c.debug) {
ts.benchmark('saveSort widget: Saving last sort: ' + c.sortList, time);
}
}
} else {
// set table sort on initial run of the widget
$table.addClass('hasSaveSort');
sortList = '';
// get data
if (ts.storage) {
stored = ts.storage( table, 'tablesorter-savesort' );
sortList = (stored && stored.hasOwnProperty('sortList') && $.isArray(stored.sortList)) ? stored.sortList : '';
if (c.debug) {
ts.benchmark('saveSort: Last sort loaded: "' + sortList + '"', time);
}
$table.bind('saveSortReset', function(event) {
event.stopPropagation();
ts.storage( table, 'tablesorter-savesort', '' );
});
}
// init is true when widget init is run, this will run this widget before all other widgets have initialized
// this method allows using this widget in the original tablesorter plugin; but then it will run all widgets twice.
if (init && sortList && sortList.length > 0) {
c.sortList = sortList;
} else if (table.hasInitialized && sortList && sortList.length > 0) {
// update sort change
$table.trigger('sorton', [ sortList ]);
}
}
} else {
// set table sort on initial run of the widget
$table.addClass('hasSaveSort');
sortList = '';
// get data
if (ts.storage) {
stored = ts.storage( table, 'tablesorter-savesort' );
sortList = (stored && stored.hasOwnProperty('sortList') && $.isArray(stored.sortList)) ? stored.sortList : '';
if (c.debug) {
ts.benchmark('saveSort: Last sort loaded: "' + sortList + '"', time);
}
$table.bind('saveSortReset', function(event) {
event.stopPropagation();
ts.storage( table, 'tablesorter-savesort', '' );
});
}
// init is true when widget init is run, this will run this widget before all other widgets have initialized
// this method allows using this widget in the original tablesorter plugin; but then it will run all widgets twice.
if (init && sortList && sortList.length > 0) {
c.sortList = sortList;
} else if (table.hasInitialized && sortList && sortList.length > 0) {
// update sort change
$table.trigger('sorton', [sortList]);
}
},
remove: function(table, c) {
c.$table.removeClass('hasSaveSort');
// clear storage
if (ts.storage) { ts.storage( table, 'tablesorter-savesort', '' ); }
}
},
remove: function(table, c) {
c.$table.removeClass('hasSaveSort');
// clear storage
if (ts.storage) { ts.storage( table, 'tablesorter-savesort', '' ); }
}
});
});
})(jQuery);

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +1,128 @@
/*! Widget: sort2Hash - updated 7/21/2015 (v2.22.4) */
;( function( $ ) {
'use strict';
var ts = $.tablesorter || {},
s2h = {
init : function( c, wo ) {
var hasSaveSort = ts.hasWidget( c.table, 'saveSort' ),
sort = s2h.getSort( c, wo );
if ( ( sort && !hasSaveSort ) || ( sort && hasSaveSort && wo.sort2Hash_overrideSaveSort ) ) {
s2h.processHash( c, wo, sort );
}
c.$table.on( 'sortEnd.sort2hash', function() {
s2h.setHash( c, wo );
});
},
getTableId : function( c, wo ) {
// option > table id > table index on page
return wo.sort2Hash_tableId ||
c.table.id ||
'table' + $( 'table' ).index( c.$table );
},
getSort : function( c, wo, clean ) {
// modified original code from http://www.netlobo.com/url_query_string_javascript.html
var value,
name = s2h.getTableId( c, wo ).replace( /[\[]/, '\\[' ).replace( /[\]]/, '\\]' ),
sort = ( new RegExp( '[\\#&]' + name + '=([^&]*)' ) ).exec( window.location.hash );
if ( sort === null ) {
return '';
} else {
value = s2h.processSort( c, wo, sort[ 1 ] );
if ( clean ) {
window.location.hash = window.location.hash.replace( '&' + name + '=' + sort[ 1 ], '' );
return value;
'use strict';
var ts = $.tablesorter || {},
s2h = {
init : function( c, wo ) {
var hasSaveSort = ts.hasWidget( c.table, 'saveSort' ),
sort = s2h.getSort( c, wo );
if ( ( sort && !hasSaveSort ) || ( sort && hasSaveSort && wo.sort2Hash_overrideSaveSort ) ) {
s2h.processHash( c, wo, sort );
}
return sort[ 1 ];
}
},
// convert 'first%20name,asc,last%20name,desc' into [[0,0], [1,1]]
processHash : function( c, wo, sortHash ) {
var regex, column, direction, temp,
arry = decodeURI( sortHash || '' ).split( wo.sort2Hash_separator ),
indx = 0,
len = arry.length,
sort = [];
while ( indx < len ) {
// column index or text
column = arry[ indx++ ];
temp = parseInt( column, 10 );
// ignore wo.sort2Hash_useHeaderText setting &
// just see if column contains a number
if ( isNaN( temp ) || temp > c.columns ) {
regex = new RegExp( '(' + column + ')', 'i' );
column = c.$headers.filter( function( index, cell ) {
return regex.test( c.$headers[ index ].textContent || '' );
}).attr( 'data-column' );
}
direction = arry[ indx++ ];
// ignore unpaired values
if ( typeof direction !== 'undefined' ) {
// convert text to 0, 1
if ( isNaN( direction ) ) {
// default to ascending sort
direction = direction.indexOf( wo.sort2Hash_directionText[ 1 ] ) > -1 ? 1 : 0;
c.$table.on( 'sortEnd.sort2hash', function() {
s2h.setHash( c, wo );
});
},
getTableId : function( c, wo ) {
// option > table id > table index on page
return wo.sort2Hash_tableId ||
c.table.id ||
'table' + $( 'table' ).index( c.$table );
},
getSort : function( c, wo, clean ) {
// modified original code from http://www.netlobo.com/url_query_string_javascript.html
var value,
name = s2h.getTableId( c, wo ).replace( /[\[]/, '\\[' ).replace( /[\]]/, '\\]' ),
sort = ( new RegExp( '[\\#&]' + name + '=([^&]*)' ) ).exec( window.location.hash );
if ( sort === null ) {
return '';
} else {
value = s2h.processSort( c, wo, sort[ 1 ] );
if ( clean ) {
window.location.hash = window.location.hash.replace( '&' + name + '=' + sort[ 1 ], '' );
return value;
}
sort.push( [ column, direction ] );
return sort[ 1 ];
}
}
if ( sort.length ) {
c.sortList = sort;
}
},
// convert [[0,0],[1,1]] to 'first%20name,asc,last%20name,desc'
processSort : function( c, wo ) {
var index, txt, column, direction,
sort = [],
arry = c.sortList || [],
len = arry.length;
for ( index = 0; index < len; index++ ) {
column = arry[ index ][ 0 ];
if ( wo.sort2Hash_useHeaderText ) {
txt = $.trim( c.$headerIndexed[ column ].text() );
if ( typeof wo.sort2Hash_processHeaderText === 'function' ) {
txt = wo.sort2Hash_processHeaderText( txt, c, column );
},
// convert 'first%20name,asc,last%20name,desc' into [[0,0], [1,1]]
processHash : function( c, wo, sortHash ) {
var regex, column, direction, temp,
arry = decodeURI( sortHash || '' ).split( wo.sort2Hash_separator ),
indx = 0,
len = arry.length,
sort = [];
while ( indx < len ) {
// column index or text
column = arry[ indx++ ];
temp = parseInt( column, 10 );
// ignore wo.sort2Hash_useHeaderText setting &
// just see if column contains a number
if ( isNaN( temp ) || temp > c.columns ) {
regex = new RegExp( '(' + column + ')', 'i' );
column = c.$headers.filter( function( index, cell ) {
return regex.test( c.$headers[ index ].textContent || '' );
}).attr( 'data-column' );
}
direction = arry[ indx++ ];
// ignore unpaired values
if ( typeof direction !== 'undefined' ) {
// convert text to 0, 1
if ( isNaN( direction ) ) {
// default to ascending sort
direction = direction.indexOf( wo.sort2Hash_directionText[ 1 ] ) > -1 ? 1 : 0;
}
sort.push( [ column, direction ] );
}
column = txt;
}
sort.push( column );
direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ];
sort.push( direction );
if ( sort.length ) {
c.sortList = sort;
}
},
}
// join with separator
return sort.join( wo.sort2Hash_separator );
},
setHash : function( c, wo ) {
var arry = [],
sort = s2h.processSort( c, wo );
if ( sort.length ) {
// remove old hash
s2h.getSort( c, wo, true );
window.location.hash += ( window.location.hash.length ? '' : wo.sort2Hash_hash ) +
'&' + s2h.getTableId( c, wo ) + '=' + encodeURI( sort );
}
}
};
// convert [[0,0],[1,1]] to 'first%20name,asc,last%20name,desc'
processSort : function( c, wo ) {
var index, txt, column, direction,
sort = [],
arry = c.sortList || [],
len = arry.length;
for ( index = 0; index < len; index++ ) {
column = arry[ index ][ 0 ];
if ( wo.sort2Hash_useHeaderText ) {
txt = $.trim( c.$headerIndexed[ column ].text() );
if ( typeof wo.sort2Hash_processHeaderText === 'function' ) {
txt = wo.sort2Hash_processHeaderText( txt, c, column );
}
column = txt;
}
sort.push( column );
direction = wo.sort2Hash_directionText[ arry[ index ][ 1 ] ];
sort.push( direction );
ts.addWidget({
id: 'sort2Hash',
priority: 30, // after saveSort
options: {
sort2Hash_hash : '#', // hash prefix
sort2Hash_separator : '-', // don't '#' or '=' here
sort2Hash_tableId : null, // this option > table ID > table index on page,
sort2Hash_useHeaderText : false, // use column header text (true) or zero-based column index
sort2Hash_processHeaderText : null, // function( text, config, columnIndex ) {},
sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
sort2Hash_overrideSaveSort : false // if true, override saveSort widget if saved sort available
},
init: function(table, thisWidget, c, wo) {
s2h.init( c, wo );
},
remove: function(table, c) {
c.$table.off( 'sortEnd.sort2hash' );
}
});
}
// join with separator
return sort.join( wo.sort2Hash_separator );
},
setHash : function( c, wo ) {
var arry = [],
sort = s2h.processSort( c, wo );
if ( sort.length ) {
// remove old hash
s2h.getSort( c, wo, true );
window.location.hash += ( window.location.hash.length ? '' : wo.sort2Hash_hash ) +
'&' + s2h.getTableId( c, wo ) + '=' + encodeURI( sort );
}
}
};
ts.addWidget({
id: 'sort2Hash',
priority: 30, // after saveSort
options: {
sort2Hash_hash : '#', // hash prefix
sort2Hash_separator : '-', // don't '#' or '=' here
sort2Hash_tableId : null, // this option > table ID > table index on page,
sort2Hash_useHeaderText : false, // use column header text (true) or zero-based column index
sort2Hash_processHeaderText : null, // function( text, config, columnIndex ) {},
sort2Hash_directionText : [ 0, 1 ], // [ 'asc', 'desc' ],
sort2Hash_overrideSaveSort : false // if true, override saveSort widget if saved sort available
},
init: function(table, thisWidget, c, wo) {
s2h.init( c, wo );
},
remove: function(table, c) {
c.$table.off( 'sortEnd.sort2hash' );
}
});
})(jQuery);

View File

@ -5,224 +5,224 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;( function( $ ) {
'use strict';
var ts = $.tablesorter;
'use strict';
var ts = $.tablesorter;
ts.sortTbodies = {
init: function( c, wo ) {
ts.sortTbodies = {
init: function( c, wo ) {
var index, rows, txt, max, $rows,
namespace = c.namespace + 'sortTbody',
$tbodies = c.$table.children( 'tbody' ),
len = $tbodies.length;
var index, rows, txt, max, $rows,
namespace = c.namespace + 'sortTbody',
$tbodies = c.$table.children( 'tbody' ),
len = $tbodies.length;
// save serverSideSorting value; use to toggle internal row sorting
wo.sortTbody_original_serverSideSorting = c.serverSideSorting;
// save serverSideSorting value; use to toggle internal row sorting
wo.sortTbody_original_serverSideSorting = c.serverSideSorting;
// include info-only tbodies - we need parsed data from *all* tbodies
wo.sortTbody_original_cssInfoBlock = c.cssInfoBlock;
c.cssInfoBlock = wo.sortTbody_noSort;
ts.sortTbodies.setTbodies( c, wo );
// add original order index for stable sort
for ( index = 0; index < len; index++ ) {
$tbodies.eq( index ).attr( 'data-ts-original-order', index );
}
c.$table
.unbind( 'sortBegin updateComplete '.split( ' ' ).join( namespace + ' ' ) )
.bind( 'sortBegin' + namespace, function() {
ts.sortTbodies.sorter( c );
})
.bind( 'updateComplete' + namespace, function() {
// find parsers for each column
ts.sortTbodies.setTbodies( c, wo );
c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
});
// detect parsers - in case the table contains only info-only tbodies
if ( $.isEmptyObject( c.parsers ) || c.$tbodies.length !== $tbodies.length ) {
// include info-only tbodies - we need parsed data from *all* tbodies
wo.sortTbody_original_cssInfoBlock = c.cssInfoBlock;
c.cssInfoBlock = wo.sortTbody_noSort;
ts.sortTbodies.setTbodies( c, wo );
c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
}
// find colMax; this only matter for numeric columns
$rows = $tbodies.children( 'tr' );
len = $rows.length;
for ( index = 0; index < c.columns; index++ ) {
max = 0;
if ( c.parsers[ index ].type === 'numeric' ) {
for ( rows = 0; rows < len; rows++ ) {
// update column max value (ignore sign)
txt = ts.getParsedText( c, $rows.eq( rows ).children()[ index ], index );
max = Math.max( Math.abs( txt ) || 0, max );
}
// add original order index for stable sort
for ( index = 0; index < len; index++ ) {
$tbodies.eq( index ).attr( 'data-ts-original-order', index );
}
c.$headerIndexed[ index ].attr( 'data-ts-col-max-value', max );
}
},
// make sure c.$tbodies is up-to-date (init & after updates)
setTbodies: function( c, wo ) {
c.$tbodies = c.$table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort );
},
sorter: function( c ) {
var $table = c.$table,
wo = c.widgetOptions;
// prevent multiple calls while processing
if ( wo.sortTbody_busy !== true ) {
wo.sortTbody_busy = true;
var $tbodies = $table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort ),
primary = wo.sortTbody_primaryRow || 'tr:eq(0)',
sortList = c.sortList || [],
len = sortList.length;
if ( len ) {
// toggle internal row sorting
c.serverSideSorting = !wo.sortTbody_sortRows;
$tbodies.sort( function( a, b ) {
var sortListIndex, txt, dir, num, colMax, sort, col, order, colA, colB, x, y,
table = c.table,
parsers = c.parsers,
cts = c.textSorter || '',
$tbodyA = $( a ),
$tbodyB = $( b ),
$a = $tbodyA.find( primary ).children( 'td, th' ),
$b = $tbodyB.find( primary ).children( 'td, th' );
for ( sortListIndex = 0; sortListIndex < len; sortListIndex++ ) {
col = sortList[ sortListIndex ][0];
order = sortList[ sortListIndex ][1];
// sort direction, true = asc, false = desc
dir = order === 0;
// column txt - tbody A
txt = ts.getElementText( c, $a.eq( col ), col );
colA = parsers[ col ].format( txt, table, $a[ col ], col );
// column txt - tbody B
txt = ts.getElementText( c, $b.eq( col ), col );
colB = parsers[ col ].format( txt, table, $b[ col ], col );
if (c.sortStable && colA === colB && len === 1) {
return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
}
// fallback to natural sort since it is more robust
num = /n/i.test( parsers && parsers[ col ] ? parsers[ col ].type || '' : '' );
if ( num && c.strings[ col ] ) {
colMax = c.$headerIndexed[ col ].attr( 'data-ts-col-max-value' ) ||
1.79E+308; // close to Number.MAX_VALUE
// sort strings in numerical columns
if ( typeof ( c.string[ c.strings[ col ] ] ) === 'boolean' ) {
num = ( dir ? 1 : -1 ) * ( c.string[ c.strings[ col ] ] ? -1 : 1 );
} else {
num = ( c.strings[ col ] ) ? c.string[ c.strings[ col ] ] || 0 : 0;
}
// fall back to built-in numeric sort
// var sort = $.tablesorter['sort' + s](a, b, dir, colMax, table);
sort = c.numberSorter ? c.numberSorter( colA, colB, dir, colMax, table ) :
ts[ 'sortNumeric' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, num, colMax, col, table );
} else {
// set a & b depending on sort direction
x = dir ? colA : colB;
y = dir ? colB : colA;
// text sort function
if ( typeof ( cts ) === 'function' ) {
// custom OVERALL text sorter
sort = cts( x, y, dir, col, table );
} else if ( typeof ( cts ) === 'object' && cts.hasOwnProperty( col ) ) {
// custom text sorter for a SPECIFIC COLUMN
sort = cts[ col ]( x, y, dir, col, table );
} else {
// fall back to natural sort
sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, col, table, c );
}
}
if ( sort ) { return sort; }
}
return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
c.$table
.unbind( 'sortBegin updateComplete '.split( ' ' ).join( namespace + ' ' ) )
.bind( 'sortBegin' + namespace, function() {
ts.sortTbodies.sorter( c );
})
.bind( 'updateComplete' + namespace, function() {
// find parsers for each column
ts.sortTbodies.setTbodies( c, wo );
c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
});
ts.sortTbodies.restoreTbodies ( c, wo, $tbodies );
wo.sortTbody_busy = false;
// detect parsers - in case the table contains only info-only tbodies
if ( $.isEmptyObject( c.parsers ) || c.$tbodies.length !== $tbodies.length ) {
ts.sortTbodies.setTbodies( c, wo );
c.$table.trigger( 'updateCache', [ null, c.$tbodies ] );
}
}
},
restoreTbodies : function ( c, wo, $sortedTbodies ) {
var $nosort, $tbodies, $thisTbody, tbLen, nsLen, index, targetIndex,
$table = c.$table,
hasShuffled = true,
indx = 0;
// hide entire table to improve sort performance
$table.hide();
$sortedTbodies.appendTo( $table );
// reposition no-sort tbodies
$tbodies = $table.children( 'tbody' );
tbLen = $tbodies.length;
$nosort = $tbodies.filter( '.' + wo.sortTbody_noSort ).appendTo( $table );
nsLen = $nosort.length;
if ( nsLen ) {
// don't allow the while loop to cycle more times than the set number of no-sort tbodies
while ( hasShuffled && indx < nsLen ) {
hasShuffled = false;
for ( index = 0; index < nsLen; index++ ) {
targetIndex = parseInt( $nosort.eq( index ).attr( 'data-ts-original-order' ), 10 );
// if target index > number of tbodies, make it last
targetIndex = targetIndex >= tbLen ? tbLen : targetIndex < 0 ? 0 : targetIndex;
if ( targetIndex !== $nosort.eq( index ).index() ) {
hasShuffled = true;
$thisTbody = $nosort.eq( index ).detach();
if ( targetIndex >= tbLen ) {
// Are we trying to be the last tbody?
$thisTbody.appendTo( $table );
} else if ( targetIndex === 0 ) {
// Are we trying to be the first tbody?
$thisTbody.prependTo( $table );
} else {
// No, we want to be somewhere in the middle!
$thisTbody.insertBefore( $table.children( 'tbody:eq(' + targetIndex + ')' ) );
}
// find colMax; this only matter for numeric columns
$rows = $tbodies.children( 'tr' );
len = $rows.length;
for ( index = 0; index < c.columns; index++ ) {
max = 0;
if ( c.parsers[ index ].type === 'numeric' ) {
for ( rows = 0; rows < len; rows++ ) {
// update column max value (ignore sign)
txt = ts.getParsedText( c, $rows.eq( rows ).children()[ index ], index );
max = Math.max( Math.abs( txt ) || 0, max );
}
}
indx++;
c.$headerIndexed[ index ].attr( 'data-ts-col-max-value', max );
}
},
// make sure c.$tbodies is up-to-date (init & after updates)
setTbodies: function( c, wo ) {
c.$tbodies = c.$table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort );
},
sorter: function( c ) {
var $table = c.$table,
wo = c.widgetOptions;
// prevent multiple calls while processing
if ( wo.sortTbody_busy !== true ) {
wo.sortTbody_busy = true;
var $tbodies = $table.children( 'tbody' ).not( '.' + wo.sortTbody_noSort ),
primary = wo.sortTbody_primaryRow || 'tr:eq(0)',
sortList = c.sortList || [],
len = sortList.length;
if ( len ) {
// toggle internal row sorting
c.serverSideSorting = !wo.sortTbody_sortRows;
$tbodies.sort( function( a, b ) {
var sortListIndex, txt, dir, num, colMax, sort, col, order, colA, colB, x, y,
table = c.table,
parsers = c.parsers,
cts = c.textSorter || '',
$tbodyA = $( a ),
$tbodyB = $( b ),
$a = $tbodyA.find( primary ).children( 'td, th' ),
$b = $tbodyB.find( primary ).children( 'td, th' );
for ( sortListIndex = 0; sortListIndex < len; sortListIndex++ ) {
col = sortList[ sortListIndex ][0];
order = sortList[ sortListIndex ][1];
// sort direction, true = asc, false = desc
dir = order === 0;
// column txt - tbody A
txt = ts.getElementText( c, $a.eq( col ), col );
colA = parsers[ col ].format( txt, table, $a[ col ], col );
// column txt - tbody B
txt = ts.getElementText( c, $b.eq( col ), col );
colB = parsers[ col ].format( txt, table, $b[ col ], col );
if (c.sortStable && colA === colB && len === 1) {
return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
}
// fallback to natural sort since it is more robust
num = /n/i.test( parsers && parsers[ col ] ? parsers[ col ].type || '' : '' );
if ( num && c.strings[ col ] ) {
colMax = c.$headerIndexed[ col ].attr( 'data-ts-col-max-value' ) ||
1.79E+308; // close to Number.MAX_VALUE
// sort strings in numerical columns
if ( typeof ( c.string[ c.strings[ col ] ] ) === 'boolean' ) {
num = ( dir ? 1 : -1 ) * ( c.string[ c.strings[ col ] ] ? -1 : 1 );
} else {
num = ( c.strings[ col ] ) ? c.string[ c.strings[ col ] ] || 0 : 0;
}
// fall back to built-in numeric sort
// var sort = $.tablesorter['sort' + s](a, b, dir, colMax, table);
sort = c.numberSorter ? c.numberSorter( colA, colB, dir, colMax, table ) :
ts[ 'sortNumeric' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, num, colMax, col, table );
} else {
// set a & b depending on sort direction
x = dir ? colA : colB;
y = dir ? colB : colA;
// text sort function
if ( typeof ( cts ) === 'function' ) {
// custom OVERALL text sorter
sort = cts( x, y, dir, col, table );
} else if ( typeof ( cts ) === 'object' && cts.hasOwnProperty( col ) ) {
// custom text sorter for a SPECIFIC COLUMN
sort = cts[ col ]( x, y, dir, col, table );
} else {
// fall back to natural sort
sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( colA, colB, col, table, c );
}
}
if ( sort ) { return sort; }
}
return $tbodyA.attr( 'data-ts-original-order' ) - $tbodyB.attr( 'data-ts-original-order' );
});
ts.sortTbodies.restoreTbodies( c, wo, $tbodies );
wo.sortTbody_busy = false;
}
}
},
restoreTbodies : function ( c, wo, $sortedTbodies ) {
var $nosort, $tbodies, $thisTbody, tbLen, nsLen, index, targetIndex,
$table = c.$table,
hasShuffled = true,
indx = 0;
// hide entire table to improve sort performance
$table.hide();
$sortedTbodies.appendTo( $table );
// reposition no-sort tbodies
$tbodies = $table.children( 'tbody' );
tbLen = $tbodies.length;
$nosort = $tbodies.filter( '.' + wo.sortTbody_noSort ).appendTo( $table );
nsLen = $nosort.length;
if ( nsLen ) {
// don't allow the while loop to cycle more times than the set number of no-sort tbodies
while ( hasShuffled && indx < nsLen ) {
hasShuffled = false;
for ( index = 0; index < nsLen; index++ ) {
targetIndex = parseInt( $nosort.eq( index ).attr( 'data-ts-original-order' ), 10 );
// if target index > number of tbodies, make it last
targetIndex = targetIndex >= tbLen ? tbLen : targetIndex < 0 ? 0 : targetIndex;
if ( targetIndex !== $nosort.eq( index ).index() ) {
hasShuffled = true;
$thisTbody = $nosort.eq( index ).detach();
if ( targetIndex >= tbLen ) {
// Are we trying to be the last tbody?
$thisTbody.appendTo( $table );
} else if ( targetIndex === 0 ) {
// Are we trying to be the first tbody?
$thisTbody.prependTo( $table );
} else {
// No, we want to be somewhere in the middle!
$thisTbody.insertBefore( $table.children( 'tbody:eq(' + targetIndex + ')' ) );
}
}
}
indx++;
}
}
$table.show();
}
$table.show();
}
};
};
ts.addWidget({
id: 'sortTbody',
// priority < 50 (filter widget), so c.$tbodies has the correct elements
priority: 40,
options: {
// point to a row within the tbody that matches the number of header columns
sortTbody_primaryRow : null,
// sort tbody internal rows
sortTbody_sortRows : false,
// static tbodies (like static rows)
sortTbody_noSort : 'tablesorter-no-sort-tbody'
},
init : function( table, thisWidget, c, wo ) {
ts.sortTbodies.init( c, wo );
},
remove : function( table, c, wo, refreshing ) {
c.$table.unbind( 'sortBegin updateComplete '.split( ' ' ).join( c.namespace + 'sortTbody ' ) );
c.serverSideSorting = wo.sortTbody_original_serverSideSorting;
c.cssInfoBlock = wo.sortTbody_original_cssInfoBlock;
}
});
ts.addWidget({
id: 'sortTbody',
// priority < 50 (filter widget), so c.$tbodies has the correct elements
priority: 40,
options: {
// point to a row within the tbody that matches the number of header columns
sortTbody_primaryRow : null,
// sort tbody internal rows
sortTbody_sortRows : false,
// static tbodies (like static rows)
sortTbody_noSort : 'tablesorter-no-sort-tbody'
},
init : function( table, thisWidget, c, wo ) {
ts.sortTbodies.init( c, wo );
},
remove : function( table, c, wo, refreshing ) {
c.$table.unbind( 'sortBegin updateComplete '.split( ' ' ).join( c.namespace + 'sortTbody ' ) );
c.serverSideSorting = wo.sortTbody_original_serverSideSorting;
c.cssInfoBlock = wo.sortTbody_original_cssInfoBlock;
}
});
})( jQuery );

View File

@ -12,110 +12,110 @@
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
"use strict";
var ts = $.tablesorter,
'use strict';
var ts = $.tablesorter,
// add/refresh row indexes
addIndexes = function(table){
var $tr, wo, v, indx, rows,
c = table.config;
// "Index" the static rows, saving their current (starting) position in the
// table inside a data() param on the <tr> element itself for later use.
if (c) {
wo = c.widgetOptions;
c.$tbodies.each(function(){
$tr = $(this).children();
rows = $tr.length;
$tr.filter(wo.staticRow_class).each(function() {
$tr = $(this);
indx = $tr.data(wo.staticRow_index);
if (typeof indx !== "undefined") {
v = parseFloat(indx);
// percentage of total rows
indx = (/%/.test(indx)) ? Math.round(v/100 * rows) : v;
} else {
indx = $tr.index();
}
// row indexing starts over within each tbody
$tr.data( wo.staticRow_data, indx );
// add/refresh row indexes
addIndexes = function(table){
var $tr, wo, v, indx, rows,
c = table.config;
// 'Index' the static rows, saving their current (starting) position in the
// table inside a data() param on the <tr> element itself for later use.
if (c) {
wo = c.widgetOptions;
c.$tbodies.each(function(){
$tr = $(this).children();
rows = $tr.length;
$tr.filter(wo.staticRow_class).each(function() {
$tr = $(this);
indx = $tr.data(wo.staticRow_index);
if (typeof indx !== 'undefined') {
v = parseFloat(indx);
// percentage of total rows
indx = (/%/.test(indx)) ? Math.round(v / 100 * rows) : v;
} else {
indx = $tr.index();
}
// row indexing starts over within each tbody
$tr.data( wo.staticRow_data, indx );
});
});
});
}
};
}
};
ts.addWidget({
// Give the new Widget an ID to be used in the tablesorter() call, as follows:
// $('#myElement').tablesorter({ widgets: ['zebra', 'staticRow'] });
id: 'staticRow',
ts.addWidget({
// Give the new Widget an ID to be used in the tablesorter() call, as follows:
// $('#myElement').tablesorter({ widgets: ['zebra', 'staticRow'] });
id: 'staticRow',
options: {
staticRow_class : '.static',
staticRow_data : 'static-index',
staticRow_index : 'row-index',
staticRow_event : 'staticRowsRefresh'
},
options: {
staticRow_class : '.static',
staticRow_data : 'static-index',
staticRow_index : 'row-index',
staticRow_event : 'staticRowsRefresh'
},
init: function(table, thisWidget, c, wo){
addIndexes(table);
// refresh static rows after updates
c.$table
.unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') )
.bind('updateComplete.tsstaticrows ' + wo.staticRow_event, function(){
addIndexes(table);
c.$table.trigger('applyWidgets');
});
},
init: function(table, thisWidget, c, wo){
addIndexes(table);
// refresh static rows after updates
c.$table
.unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') )
.bind('updateComplete.tsstaticrows ' + wo.staticRow_event, function(){
addIndexes(table);
c.$table.trigger('applyWidgets');
});
},
format: function(table, c, wo) {
// Loop thru static rows, moving them to their original "indexed" position,
// & repeat until no more re-shuffling is needed
var targetIndex, $thisRow, indx, numRows, $tbody, hasShuffled, $rows, max;
format: function(table, c, wo) {
// Loop thru static rows, moving them to their original 'indexed' position,
// & repeat until no more re-shuffling is needed
var targetIndex, $thisRow, indx, numRows, $tbody, hasShuffled, $rows, max;
c.$tbodies.each(function(){
$tbody = $.tablesorter.processTbody(table, $(this), true); // remove tbody
hasShuffled = true;
indx = 0;
$rows = $tbody.children(wo.staticRow_class);
numRows = $tbody.children('tr').length - 1;
max = $rows.length;
c.$tbodies.each(function(){
$tbody = $.tablesorter.processTbody(table, $(this), true); // remove tbody
hasShuffled = true;
indx = 0;
$rows = $tbody.children(wo.staticRow_class);
numRows = $tbody.children('tr').length - 1;
max = $rows.length;
// don't allow the while loop to cycle more times than the set number of static rows
while (hasShuffled && indx < max) {
hasShuffled = false;
/*jshint loopfunc:true */
$rows.each(function() {
targetIndex = $(this).data(wo.staticRow_data);
// allow setting target index >> num rows to always make a row last
targetIndex = targetIndex >= numRows ? numRows : targetIndex < 0 ? 0 : targetIndex;
if (targetIndex !== $(this).index()) {
hasShuffled = true;
$thisRow = $(this).detach();
// don't allow the while loop to cycle more times than the set number of static rows
while (hasShuffled && indx < max) {
hasShuffled = false;
/*jshint loopfunc:true */
$rows.each(function() {
targetIndex = $(this).data(wo.staticRow_data);
// allow setting target index >> num rows to always make a row last
targetIndex = targetIndex >= numRows ? numRows : targetIndex < 0 ? 0 : targetIndex;
if (targetIndex !== $(this).index()) {
hasShuffled = true;
$thisRow = $(this).detach();
if (targetIndex >= numRows) {
// Are we trying to be the last row?
$thisRow.appendTo( $tbody );
} else if (targetIndex === 0) {
if (targetIndex >= numRows) {
// Are we trying to be the last row?
$thisRow.appendTo( $tbody );
} else if (targetIndex === 0) {
// Are we trying to be the first row?
$thisRow.prependTo( $tbody );
} else {
// No, we want to be somewhere in the middle!
$thisRow.insertBefore( $tbody.find('tr:eq(' + targetIndex + ')') );
} else {
// No, we want to be somewhere in the middle!
$thisRow.insertBefore( $tbody.find('tr:eq(' + targetIndex + ')') );
}
}
}
});
indx++;
}
});
indx++;
}
$.tablesorter.processTbody(table, $tbody, false); // restore tbody
});
$.tablesorter.processTbody(table, $tbody, false); // restore tbody
});
c.$table.trigger('staticRowsComplete', table);
},
c.$table.trigger('staticRowsComplete', table);
},
remove : function(table, c, wo){
c.$table.unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') );
}
remove : function(table, c, wo){
c.$table.unbind( ('updateComplete.tsstaticrows ' + wo.staticRow_event).replace(/\s+/g, ' ') );
}
});
});
})(jQuery);

View File

@ -3,286 +3,286 @@
* by Rob Garrison
*/
;(function ($, window) {
'use strict';
var ts = $.tablesorter || {};
'use strict';
var ts = $.tablesorter || {};
$.extend(ts.css, {
sticky : 'tablesorter-stickyHeader', // stickyHeader
stickyVis : 'tablesorter-sticky-visible',
stickyHide: 'tablesorter-sticky-hidden',
stickyWrap: 'tablesorter-sticky-wrapper'
});
$.extend(ts.css, {
sticky : 'tablesorter-stickyHeader', // stickyHeader
stickyVis : 'tablesorter-sticky-visible',
stickyHide: 'tablesorter-sticky-hidden',
stickyWrap: 'tablesorter-sticky-wrapper'
});
// Add a resize event to table headers
ts.addHeaderResizeEvent = function(table, disable, settings) {
table = $(table)[0]; // make sure we're using a dom element
if ( !table.config ) { return; }
var defaults = {
timer : 250
// Add a resize event to table headers
ts.addHeaderResizeEvent = function(table, disable, settings) {
table = $(table)[0]; // make sure we're using a dom element
if ( !table.config ) { return; }
var defaults = {
timer : 250
},
options = $.extend({}, defaults, settings),
c = table.config,
wo = c.widgetOptions,
checkSizes = function( triggerEvent ) {
var index, headers, $header, sizes, width, height,
len = c.$headers.length;
wo.resize_flag = true;
headers = [];
for ( index = 0; index < len; index++ ) {
$header = c.$headers.eq( index );
sizes = $header.data( 'savedSizes' ) || [ 0, 0 ]; // fixes #394
width = $header[0].offsetWidth;
height = $header[0].offsetHeight;
if ( width !== sizes[0] || height !== sizes[1] ) {
$header.data( 'savedSizes', [ width, height ] );
headers.push( $header[0] );
}
}
if ( headers.length && triggerEvent !== false ) {
c.$table.trigger( 'resize', [ headers ] );
}
wo.resize_flag = false;
};
checkSizes( false );
clearInterval(wo.resize_timer);
if (disable) {
wo.resize_flag = false;
return false;
}
wo.resize_timer = setInterval(function() {
if (wo.resize_flag) { return; }
checkSizes();
}, options.timer);
};
// Sticky headers based on this awesome article:
// http://css-tricks.com/13465-persistent-headers/
// and https://github.com/jmosbech/StickyTableHeaders by Jonas Mosbech
// **************************
ts.addWidget({
id: 'stickyHeaders',
priority: 60, // sticky widget must be initialized after the filter widget!
options: {
stickyHeaders : '', // extra class name added to the sticky header row
stickyHeaders_attachTo : null, // jQuery selector or object to attach sticky header to
stickyHeaders_xScroll : null, // jQuery selector or object to monitor horizontal scroll position (defaults: xScroll > attachTo > window)
stickyHeaders_yScroll : null, // jQuery selector or object to monitor vertical scroll position (defaults: yScroll > attachTo > window)
stickyHeaders_offset : 0, // number or jquery selector targeting the position:fixed element
stickyHeaders_filteredToTop: true, // scroll table top into view after filtering
stickyHeaders_cloneId : '-sticky', // added to table ID, if it exists
stickyHeaders_addResizeEvent : true, // trigger 'resize' event on headers
stickyHeaders_includeCaption : true, // if false and a caption exist, it won't be included in the sticky header
stickyHeaders_zIndex : 2 // The zIndex of the stickyHeaders, allows the user to adjust this to their needs
},
options = $.extend({}, defaults, settings),
c = table.config,
wo = c.widgetOptions,
checkSizes = function( triggerEvent ) {
var index, headers, $header, sizes, width, height,
len = c.$headers.length;
wo.resize_flag = true;
headers = [];
for ( index = 0; index < len; index++ ) {
$header = c.$headers.eq( index );
sizes = $header.data( 'savedSizes' ) || [ 0,0 ]; // fixes #394
width = $header[0].offsetWidth;
height = $header[0].offsetHeight;
if ( width !== sizes[0] || height !== sizes[1] ) {
$header.data( 'savedSizes', [ width, height ] );
headers.push( $header[0] );
format: function(table, c, wo) {
// filter widget doesn't initialize on an empty table. Fixes #449
if ( c.$table.hasClass('hasStickyHeaders') || ($.inArray('filter', c.widgets) >= 0 && !c.$table.hasClass('hasFilters')) ) {
return;
}
var index, len, $t,
$table = c.$table,
// add position: relative to attach element, hopefully it won't cause trouble.
$attach = $(wo.stickyHeaders_attachTo),
namespace = c.namespace + 'stickyheaders ',
// element to watch for the scroll event
$yScroll = $(wo.stickyHeaders_yScroll || wo.stickyHeaders_attachTo || window),
$xScroll = $(wo.stickyHeaders_xScroll || wo.stickyHeaders_attachTo || window),
$thead = $table.children('thead:first'),
$header = $thead.children('tr').not('.sticky-false').children(),
$tfoot = $table.children('tfoot'),
$stickyOffset = isNaN(wo.stickyHeaders_offset) ? $(wo.stickyHeaders_offset) : '',
stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0,
// is this table nested? If so, find parent sticky header wrapper (div, not table)
$nestedSticky = $table.parent().closest('.' + ts.css.table).hasClass('hasStickyHeaders') ?
$table.parent().closest('table.tablesorter')[0].config.widgetOptions.$sticky.parent() : [],
nestedStickyTop = $nestedSticky.length ? $nestedSticky.height() : 0,
// clone table, then wrap to make sticky header
$stickyTable = wo.$sticky = $table.clone()
.addClass('containsStickyHeaders ' + ts.css.sticky + ' ' + wo.stickyHeaders + ' ' + c.namespace.slice(1) + '_extra_table' )
.wrap('<div class="' + ts.css.stickyWrap + '">'),
$stickyWrap = $stickyTable.parent()
.addClass(ts.css.stickyHide)
.css({
position : $attach.length ? 'absolute' : 'fixed',
padding : parseInt( $stickyTable.parent().parent().css('padding-left'), 10 ),
top : stickyOffset + nestedStickyTop,
left : 0,
visibility : 'hidden',
zIndex : wo.stickyHeaders_zIndex || 2
}),
$stickyThead = $stickyTable.children('thead:first'),
$stickyCells,
laststate = '',
spacing = 0,
setWidth = function($orig, $clone){
var index, width, border, $cell, $this,
$cells = $orig.filter(':visible'),
len = $cells.length;
for ( index = 0; index < len; index++ ) {
$cell = $clone.filter(':visible').eq(index);
$this = $cells.eq(index);
// code from https://github.com/jmosbech/StickyTableHeaders
if ($this.css('box-sizing') === 'border-box') {
width = $this.outerWidth();
} else {
if ($cell.css('border-collapse') === 'collapse') {
if (window.getComputedStyle) {
width = parseFloat( window.getComputedStyle($this[0], null).width );
} else {
// ie8 only
border = parseFloat( $this.css('border-width') );
width = $this.outerWidth() - parseFloat( $this.css('padding-left') ) - parseFloat( $this.css('padding-right') ) - border;
}
} else {
width = $this.width();
}
}
$cell.css({
'width': width,
'min-width': width,
'max-width': width
});
}
},
resizeHeader = function() {
stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0;
spacing = 0;
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing,
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
setWidth( $header, $stickyCells );
},
scrollSticky = function( resizing ) {
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(),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
// scrollTop = ( $attach.length ? $attach.offset().top : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
scrollTop = ( $attach.length ? ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)),
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
cssSettings = { visibility : isVisible };
if ($attach.length) {
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() - spacing;
}
if ($nestedSticky.length) {
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
}
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.css(cssSettings);
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();
laststate = isVisible;
}
};
// only add a position relative if a position isn't already defined
if ($attach.length && !$attach.css('position')) {
$attach.css('position', 'relative');
}
// fix clone ID, if it exists - fixes #271
if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
// clear out cloned table, except for sticky header
// include caption & filter row (fixes #126 & #249) - don't remove cells to get correct cell indexing
$stickyTable.find('thead:gt(0), tr.sticky-false').hide();
$stickyTable.find('tbody, tfoot').remove();
$stickyTable.find('caption').toggle(wo.stickyHeaders_includeCaption);
// issue #172 - find td/th in sticky header
$stickyCells = $stickyThead.children().children();
$stickyTable.css({ height:0, width:0, margin: 0 });
// remove resizable block
$stickyCells.find('.' + ts.css.resizer).remove();
// update sticky header class names to match real header after sorting
$table
.addClass('hasStickyHeaders')
.bind('pagerComplete' + namespace, function() {
resizeHeader();
});
ts.bindEvents(table, $stickyThead.children().children('.' + ts.css.header));
// add stickyheaders AFTER the table. If the table is selected by ID, the original one (first) will be returned.
$table.after( $stickyWrap );
// onRenderHeader is defined, we need to do something about it (fixes #641)
if (c.onRenderHeader) {
$t = $stickyThead.children('tr').children();
len = $t.length;
for ( index = 0; index < len; index++ ) {
// send second parameter
c.onRenderHeader.apply( $t.eq( index ), [ index, c, $stickyTable ] );
}
}
if ( headers.length && triggerEvent !== false ) {
c.$table.trigger( 'resize', [ headers ] );
}
wo.resize_flag = false;
};
checkSizes( false );
clearInterval(wo.resize_timer);
if (disable) {
wo.resize_flag = false;
return false;
}
wo.resize_timer = setInterval(function() {
if (wo.resize_flag) { return; }
checkSizes();
}, options.timer);
};
// Sticky headers based on this awesome article:
// http://css-tricks.com/13465-persistent-headers/
// and https://github.com/jmosbech/StickyTableHeaders by Jonas Mosbech
// **************************
ts.addWidget({
id: "stickyHeaders",
priority: 60, // sticky widget must be initialized after the filter widget!
options: {
stickyHeaders : '', // extra class name added to the sticky header row
stickyHeaders_attachTo : null, // jQuery selector or object to attach sticky header to
stickyHeaders_xScroll : null, // jQuery selector or object to monitor horizontal scroll position (defaults: xScroll > attachTo > window)
stickyHeaders_yScroll : null, // jQuery selector or object to monitor vertical scroll position (defaults: yScroll > attachTo > window)
stickyHeaders_offset : 0, // number or jquery selector targeting the position:fixed element
stickyHeaders_filteredToTop: true, // scroll table top into view after filtering
stickyHeaders_cloneId : '-sticky', // added to table ID, if it exists
stickyHeaders_addResizeEvent : true, // trigger "resize" event on headers
stickyHeaders_includeCaption : true, // if false and a caption exist, it won't be included in the sticky header
stickyHeaders_zIndex : 2 // The zIndex of the stickyHeaders, allows the user to adjust this to their needs
},
format: function(table, c, wo) {
// filter widget doesn't initialize on an empty table. Fixes #449
if ( c.$table.hasClass('hasStickyHeaders') || ($.inArray('filter', c.widgets) >= 0 && !c.$table.hasClass('hasFilters')) ) {
return;
}
var index, len, $t,
$table = c.$table,
// add position: relative to attach element, hopefully it won't cause trouble.
$attach = $(wo.stickyHeaders_attachTo),
namespace = c.namespace + 'stickyheaders ',
// element to watch for the scroll event
$yScroll = $(wo.stickyHeaders_yScroll || wo.stickyHeaders_attachTo || window),
$xScroll = $(wo.stickyHeaders_xScroll || wo.stickyHeaders_attachTo || window),
$thead = $table.children('thead:first'),
$header = $thead.children('tr').not('.sticky-false').children(),
$tfoot = $table.children('tfoot'),
$stickyOffset = isNaN(wo.stickyHeaders_offset) ? $(wo.stickyHeaders_offset) : '',
stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0,
// is this table nested? If so, find parent sticky header wrapper (div, not table)
$nestedSticky = $table.parent().closest('.' + ts.css.table).hasClass('hasStickyHeaders') ?
$table.parent().closest('table.tablesorter')[0].config.widgetOptions.$sticky.parent() : [],
nestedStickyTop = $nestedSticky.length ? $nestedSticky.height() : 0,
// clone table, then wrap to make sticky header
$stickyTable = wo.$sticky = $table.clone()
.addClass('containsStickyHeaders ' + ts.css.sticky + ' ' + wo.stickyHeaders + ' ' + c.namespace.slice(1) + '_extra_table' )
.wrap('<div class="' + ts.css.stickyWrap + '">'),
$stickyWrap = $stickyTable.parent()
.addClass(ts.css.stickyHide)
.css({
position : $attach.length ? 'absolute' : 'fixed',
padding : parseInt( $stickyTable.parent().parent().css('padding-left'), 10 ),
top : stickyOffset + nestedStickyTop,
left : 0,
visibility : 'hidden',
zIndex : wo.stickyHeaders_zIndex || 2
}),
$stickyThead = $stickyTable.children('thead:first'),
$stickyCells,
laststate = '',
spacing = 0,
setWidth = function($orig, $clone){
var index, width, border, $cell, $this,
$cells = $orig.filter(':visible'),
len = $cells.length;
for ( index = 0; index < len; index++ ) {
$cell = $clone.filter(':visible').eq(index);
$this = $cells.eq(index);
// code from https://github.com/jmosbech/StickyTableHeaders
if ($this.css('box-sizing') === 'border-box') {
width = $this.outerWidth();
} else {
if ($cell.css('border-collapse') === 'collapse') {
if (window.getComputedStyle) {
width = parseFloat( window.getComputedStyle($this[0], null).width );
} else {
// ie8 only
border = parseFloat( $this.css('border-width') );
width = $this.outerWidth() - parseFloat( $this.css('padding-left') ) - parseFloat( $this.css('padding-right') ) - border;
}
} else {
width = $this.width();
// make it sticky!
$xScroll.add($yScroll)
.unbind( ('scroll resize '.split(' ').join( namespace )).replace(/\s+/g, ' ') )
.bind('scroll resize '.split(' ').join( namespace ), function( event ) {
scrollSticky( event.type === 'resize' );
});
c.$table
.unbind('stickyHeadersUpdate' + namespace)
.bind('stickyHeadersUpdate' + namespace, function(){
scrollSticky( true );
});
if (wo.stickyHeaders_addResizeEvent) {
ts.addHeaderResizeEvent(table);
}
// look for filter widget
if ($table.hasClass('hasFilters') && wo.filter_columnFilters) {
// scroll table into view after filtering, if sticky header is active - #482
$table.bind('filterEnd' + namespace, function() {
// $(':focus') needs jQuery 1.6+
var $td = $(document.activeElement).closest('td'),
column = $td.parent().children().index($td);
// only scroll if sticky header is active
if ($stickyWrap.hasClass(ts.css.stickyVis) && wo.stickyHeaders_filteredToTop) {
// scroll to original table (not sticky clone)
window.scrollTo(0, $table.position().top);
// give same input/select focus; check if c.$filters exists; fixes #594
if (column >= 0 && c.$filters) {
c.$filters.eq(column).find('a, select, input').filter(':visible').focus();
}
}
$cell.css({
'width': width,
'min-width': width,
'max-width': width
});
}
},
resizeHeader = function() {
stickyOffset = $stickyOffset.length ? $stickyOffset.height() || 0 : parseInt(wo.stickyHeaders_offset, 10) || 0;
spacing = 0;
$stickyWrap.css({
left : $attach.length ? parseInt($attach.css('padding-left'), 10) || 0 :
$table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing,
width: $table.outerWidth()
});
setWidth( $table, $stickyTable );
setWidth( $header, $stickyCells );
},
scrollSticky = function( resizing ) {
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(),
yWindow = $.isWindow( $yScroll[0] ), // $.isWindow needs jQuery 1.4.3
xWindow = $.isWindow( $xScroll[0] ),
// scrollTop = ( $attach.length ? $attach.offset().top : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
scrollTop = ( $attach.length ? ( yWindow ? $yScroll.scrollTop() : $yScroll.offset().top ) : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
tableHeight = $table.height() - ($stickyWrap.height() + ($tfoot.height() || 0)),
isVisible = ( scrollTop > offset.top ) && ( scrollTop < offset.top + tableHeight ) ? 'visible' : 'hidden',
cssSettings = { visibility : isVisible };
if ($attach.length) {
cssSettings.top = yWindow ? scrollTop - $attach.offset().top : $attach.scrollTop();
ts.filter.bindSearch( $table, $stickyCells.find('.' + ts.css.filter) );
// support hideFilters
if (wo.filter_hideFilters) {
ts.filter.hideFilters($stickyTable, c);
}
if (xWindow) {
// adjust when scrolling horizontally - fixes issue #143
cssSettings.left = $table.offset().left - parseInt($table.css('margin-left'), 10) - $xScroll.scrollLeft() - spacing;
}
if ($nestedSticky.length) {
cssSettings.top = ( cssSettings.top || 0 ) + stickyOffset + nestedStickyTop;
}
$stickyWrap
.removeClass( ts.css.stickyVis + ' ' + ts.css.stickyHide )
.addClass( isVisible === 'visible' ? ts.css.stickyVis : ts.css.stickyHide )
.css(cssSettings);
if (isVisible !== laststate || resizing) {
// make sure the column widths match
resizeHeader();
laststate = isVisible;
}
};
// only add a position relative if a position isn't already defined
if ($attach.length && !$attach.css('position')) {
$attach.css('position', 'relative');
}
// fix clone ID, if it exists - fixes #271
if ($stickyTable.attr('id')) { $stickyTable[0].id += wo.stickyHeaders_cloneId; }
// clear out cloned table, except for sticky header
// include caption & filter row (fixes #126 & #249) - don't remove cells to get correct cell indexing
$stickyTable.find('thead:gt(0), tr.sticky-false').hide();
$stickyTable.find('tbody, tfoot').remove();
$stickyTable.find('caption').toggle(wo.stickyHeaders_includeCaption);
// issue #172 - find td/th in sticky header
$stickyCells = $stickyThead.children().children();
$stickyTable.css({ height:0, width:0, margin: 0 });
// remove resizable block
$stickyCells.find('.' + ts.css.resizer).remove();
// update sticky header class names to match real header after sorting
$table
.addClass('hasStickyHeaders')
.bind('pagerComplete' + namespace, function() {
resizeHeader();
});
ts.bindEvents(table, $stickyThead.children().children('.' + ts.css.header));
// add stickyheaders AFTER the table. If the table is selected by ID, the original one (first) will be returned.
$table.after( $stickyWrap );
// onRenderHeader is defined, we need to do something about it (fixes #641)
if (c.onRenderHeader) {
$t = $stickyThead.children('tr').children();
len = $t.length;
for ( index = 0; index < len; index++ ) {
// send second parameter
c.onRenderHeader.apply( $t.eq( index ), [ index, c, $stickyTable ] );
}
$table.trigger('stickyHeadersInit');
},
remove: function(table, c, wo) {
var namespace = c.namespace + 'stickyheaders ';
c.$table
.removeClass('hasStickyHeaders')
.unbind( ('pagerComplete filterEnd stickyHeadersUpdate '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
.next('.' + ts.css.stickyWrap).remove();
if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
$(window)
.add(wo.stickyHeaders_xScroll)
.add(wo.stickyHeaders_yScroll)
.add(wo.stickyHeaders_attachTo)
.unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') );
ts.addHeaderResizeEvent(table, false);
}
// make it sticky!
$xScroll.add($yScroll)
.unbind( ('scroll resize '.split(' ').join( namespace )).replace(/\s+/g, ' ') )
.bind('scroll resize '.split(' ').join( namespace ), function( event ) {
scrollSticky( event.type === 'resize' );
});
c.$table
.unbind('stickyHeadersUpdate' + namespace)
.bind('stickyHeadersUpdate' + namespace, function(){
scrollSticky( true );
});
if (wo.stickyHeaders_addResizeEvent) {
ts.addHeaderResizeEvent(table);
}
// look for filter widget
if ($table.hasClass('hasFilters') && wo.filter_columnFilters) {
// scroll table into view after filtering, if sticky header is active - #482
$table.bind('filterEnd' + namespace, function() {
// $(':focus') needs jQuery 1.6+
var $td = $(document.activeElement).closest('td'),
column = $td.parent().children().index($td);
// only scroll if sticky header is active
if ($stickyWrap.hasClass(ts.css.stickyVis) && wo.stickyHeaders_filteredToTop) {
// scroll to original table (not sticky clone)
window.scrollTo(0, $table.position().top);
// give same input/select focus; check if c.$filters exists; fixes #594
if (column >= 0 && c.$filters) {
c.$filters.eq(column).find('a, select, input').filter(':visible').focus();
}
}
});
ts.filter.bindSearch( $table, $stickyCells.find('.' + ts.css.filter) );
// support hideFilters
if (wo.filter_hideFilters) {
ts.filter.hideFilters($stickyTable, c);
}
}
$table.trigger('stickyHeadersInit');
},
remove: function(table, c, wo) {
var namespace = c.namespace + 'stickyheaders ';
c.$table
.removeClass('hasStickyHeaders')
.unbind( ('pagerComplete filterEnd stickyHeadersUpdate '.split(' ').join(namespace)).replace(/\s+/g, ' ') )
.next('.' + ts.css.stickyWrap).remove();
if (wo.$sticky && wo.$sticky.length) { wo.$sticky.remove(); } // remove cloned table
$(window)
.add(wo.stickyHeaders_xScroll)
.add(wo.stickyHeaders_yScroll)
.add(wo.stickyHeaders_attachTo)
.unbind( ('scroll resize '.split(' ').join(namespace)).replace(/\s+/g, ' ') );
ts.addHeaderResizeEvent(table, false);
}
});
});
})(jQuery, window);

View File

@ -1,89 +1,89 @@
/*! Widget: storage - updated 3/26/2015 (v2.21.3) */
;(function ($, window, document) {
'use strict';
'use strict';
var ts = $.tablesorter || {};
// *** Store data in local storage, with a cookie fallback ***
/* IE7 needs JSON library for JSON.stringify - (http://caniuse.com/#search=json)
if you need it, then include https://github.com/douglascrockford/JSON-js
var ts = $.tablesorter || {};
// *** Store data in local storage, with a cookie fallback ***
/* IE7 needs JSON library for JSON.stringify - (http://caniuse.com/#search=json)
if you need it, then include https://github.com/douglascrockford/JSON-js
$.parseJSON is not available is jQuery versions older than 1.4.1, using older
versions will only allow storing information for one page at a time
$.parseJSON is not available is jQuery versions older than 1.4.1, using older
versions will only allow storing information for one page at a time
// *** Save data (JSON format only) ***
// val must be valid JSON... use http://jsonlint.com/ to ensure it is valid
var val = { "mywidget" : "data1" }; // valid JSON uses double quotes
// $.tablesorter.storage(table, key, val);
$.tablesorter.storage(table, 'tablesorter-mywidget', val);
// *** Save data (JSON format only) ***
// val must be valid JSON... use http://jsonlint.com/ to ensure it is valid
var val = { "mywidget" : "data1" }; // valid JSON uses double quotes
// $.tablesorter.storage(table, key, val);
$.tablesorter.storage(table, 'tablesorter-mywidget', val);
// *** Get data: $.tablesorter.storage(table, key); ***
v = $.tablesorter.storage(table, 'tablesorter-mywidget');
// val may be empty, so also check for your data
val = (v && v.hasOwnProperty('mywidget')) ? v.mywidget : '';
alert(val); // "data1" if saved, or "" if not
*/
ts.storage = function(table, key, value, options) {
table = $(table)[0];
var cookieIndex, cookies, date,
hasStorage = false,
values = {},
c = table.config,
wo = c && c.widgetOptions,
storageType = ( options && options.useSessionStorage ) || ( wo && wo.storage_useSessionStorage ) ?
'sessionStorage' : 'localStorage',
$table = $(table),
// id from (1) options ID, (2) table "data-table-group" attribute, (3) widgetOptions.storage_tableId,
// (4) table ID, then (5) table index
id = options && options.id ||
$table.attr( options && options.group || wo && wo.storage_group || 'data-table-group') ||
wo && wo.storage_tableId || table.id || $('.tablesorter').index( $table ),
// url from (1) options url, (2) table "data-table-page" attribute, (3) widgetOptions.storage_fixedUrl,
// (4) table.config.fixedUrl (deprecated), then (5) window location path
url = options && options.url ||
$table.attr(options && options.page || wo && wo.storage_page || 'data-table-page') ||
wo && wo.storage_fixedUrl || c && c.fixedUrl || window.location.pathname;
// https://gist.github.com/paulirish/5558557
if (storageType in window) {
try {
window[storageType].setItem('_tmptest', 'temp');
hasStorage = true;
window[storageType].removeItem('_tmptest');
} catch(error) {
if (c && c.debug) {
ts.log( storageType + ' is not supported in this browser' );
// *** Get data: $.tablesorter.storage(table, key); ***
v = $.tablesorter.storage(table, 'tablesorter-mywidget');
// val may be empty, so also check for your data
val = (v && v.hasOwnProperty('mywidget')) ? v.mywidget : '';
alert(val); // 'data1' if saved, or '' if not
*/
ts.storage = function(table, key, value, options) {
table = $(table)[0];
var cookieIndex, cookies, date,
hasStorage = false,
values = {},
c = table.config,
wo = c && c.widgetOptions,
storageType = ( options && options.useSessionStorage ) || ( wo && wo.storage_useSessionStorage ) ?
'sessionStorage' : 'localStorage',
$table = $(table),
// id from (1) options ID, (2) table 'data-table-group' attribute, (3) widgetOptions.storage_tableId,
// (4) table ID, then (5) table index
id = options && options.id ||
$table.attr( options && options.group || wo && wo.storage_group || 'data-table-group') ||
wo && wo.storage_tableId || table.id || $('.tablesorter').index( $table ),
// url from (1) options url, (2) table 'data-table-page' attribute, (3) widgetOptions.storage_fixedUrl,
// (4) table.config.fixedUrl (deprecated), then (5) window location path
url = options && options.url ||
$table.attr(options && options.page || wo && wo.storage_page || 'data-table-page') ||
wo && wo.storage_fixedUrl || c && c.fixedUrl || window.location.pathname;
// https://gist.github.com/paulirish/5558557
if (storageType in window) {
try {
window[storageType].setItem('_tmptest', 'temp');
hasStorage = true;
window[storageType].removeItem('_tmptest');
} catch (error) {
if (c && c.debug) {
ts.log( storageType + ' is not supported in this browser' );
}
}
}
}
// *** get value ***
if ($.parseJSON) {
if (hasStorage) {
values = $.parseJSON( window[storageType][key] || 'null' ) || {};
// *** get value ***
if ($.parseJSON) {
if (hasStorage) {
values = $.parseJSON( window[storageType][key] || 'null' ) || {};
} else {
// old browser, using cookies
cookies = document.cookie.split(/[;\s|=]/);
// add one to get from the key to the value
cookieIndex = $.inArray(key, cookies) + 1;
values = (cookieIndex !== 0) ? $.parseJSON(cookies[cookieIndex] || 'null') || {} : {};
}
}
// allow value to be an empty string too
if ((value || value === '') && window.JSON && JSON.hasOwnProperty('stringify')) {
// add unique identifiers = url pathname > table ID/index on page > data
if (!values[url]) {
values[url] = {};
}
values[url][id] = value;
// *** set value ***
if (hasStorage) {
window[storageType][key] = JSON.stringify(values);
} else {
date = new Date();
date.setTime(date.getTime() + (31536e+6)); // 365 days
document.cookie = key + '=' + (JSON.stringify(values)).replace(/\"/g, '\"') + '; expires=' + date.toGMTString() + '; path=/';
}
} else {
// old browser, using cookies
cookies = document.cookie.split(/[;\s|=]/);
// add one to get from the key to the value
cookieIndex = $.inArray(key, cookies) + 1;
values = (cookieIndex !== 0) ? $.parseJSON(cookies[cookieIndex] || 'null') || {} : {};
return values && values[url] ? values[url][id] : '';
}
}
// allow value to be an empty string too
if ((value || value === '') && window.JSON && JSON.hasOwnProperty('stringify')) {
// add unique identifiers = url pathname > table ID/index on page > data
if (!values[url]) {
values[url] = {};
}
values[url][id] = value;
// *** set value ***
if (hasStorage) {
window[storageType][key] = JSON.stringify(values);
} else {
date = new Date();
date.setTime(date.getTime() + (31536e+6)); // 365 days
document.cookie = key + '=' + (JSON.stringify(values)).replace(/\"/g,'\"') + '; expires=' + date.toGMTString() + '; path=/';
}
} else {
return values && values[url] ? values[url][id] : '';
}
};
};
})(jQuery, window, document);

View File

@ -1,185 +1,185 @@
/*! Widget: uitheme - updated 3/26/2015 (v2.21.3) */
;(function ($) {
'use strict';
var ts = $.tablesorter || {};
'use strict';
var ts = $.tablesorter || {};
ts.themes = {
'bootstrap' : {
table : 'table table-bordered table-striped',
caption : 'caption',
// header class names
header : 'bootstrap-header', // give the header a gradient background (theme.bootstrap_2.css)
sortNone : '',
sortAsc : '',
sortDesc : '',
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
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
filterRow : '', // filter row class
footerRow : '',
footerCells : '',
even : '', // even row zebra striping
odd : '' // odd row zebra striping
},
'jui' : {
table : 'ui-widget ui-widget-content ui-corner-all', // table classes
caption : 'ui-widget-content',
// header class names
header : 'ui-widget-header ui-corner-all ui-state-default', // header classes
sortNone : '',
sortAsc : '',
sortDesc : '',
active : 'ui-state-active', // applied when column is sorted
hover : 'ui-state-hover', // hover class
// icon class names
icons : 'ui-icon', // icon class added to the <i> in the header
iconSortNone : 'ui-icon-carat-2-n-s', // class name added to icon when column is not sorted
iconSortAsc : 'ui-icon-carat-1-n', // class name added to icon when column has ascending sort
iconSortDesc : 'ui-icon-carat-1-s', // class name added to icon when column has descending sort
filterRow : '',
footerRow : '',
footerCells : '',
even : 'ui-widget-content', // even row zebra striping
odd : 'ui-state-default' // odd row zebra striping
}
};
ts.themes = {
'bootstrap' : {
table : 'table table-bordered table-striped',
caption : 'caption',
// header class names
header : 'bootstrap-header', // give the header a gradient background (theme.bootstrap_2.css)
sortNone : '',
sortAsc : '',
sortDesc : '',
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
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
filterRow : '', // filter row class
footerRow : '',
footerCells : '',
even : '', // even row zebra striping
odd : '' // odd row zebra striping
},
'jui' : {
table : 'ui-widget ui-widget-content ui-corner-all', // table classes
caption : 'ui-widget-content',
// header class names
header : 'ui-widget-header ui-corner-all ui-state-default', // header classes
sortNone : '',
sortAsc : '',
sortDesc : '',
active : 'ui-state-active', // applied when column is sorted
hover : 'ui-state-hover', // hover class
// icon class names
icons : 'ui-icon', // icon class added to the <i> in the header
iconSortNone : 'ui-icon-carat-2-n-s', // class name added to icon when column is not sorted
iconSortAsc : 'ui-icon-carat-1-n', // class name added to icon when column has ascending sort
iconSortDesc : 'ui-icon-carat-1-s', // class name added to icon when column has descending sort
filterRow : '',
footerRow : '',
footerCells : '',
even : 'ui-widget-content', // even row zebra striping
odd : 'ui-state-default' // odd row zebra striping
}
};
$.extend(ts.css, {
wrapper : 'tablesorter-wrapper' // ui theme & resizable
});
$.extend(ts.css, {
wrapper : 'tablesorter-wrapper' // ui theme & resizable
});
ts.addWidget({
id: "uitheme",
priority: 10,
format: function(table, c, wo) {
var i, hdr, icon, time, $header, $icon, $tfoot, $h, oldtheme, oldremove, oldIconRmv, hasOldTheme,
themesAll = ts.themes,
$table = c.$table.add( $( c.namespace + '_extra_table' ) ),
$headers = c.$headers.add( $( c.namespace + '_extra_headers' ) ),
theme = c.theme || 'jui',
themes = themesAll[theme] || {},
remove = $.trim( [ themes.sortNone, themes.sortDesc, themes.sortAsc, themes.active ].join( ' ' ) ),
iconRmv = $.trim( [ themes.iconSortNone, themes.iconSortDesc, themes.iconSortAsc ].join( ' ' ) );
if (c.debug) { time = new Date(); }
// initialization code - run once
if (!$table.hasClass('tablesorter-' + theme) || c.theme !== c.appliedTheme || !wo.uitheme_applied) {
wo.uitheme_applied = true;
oldtheme = themesAll[c.appliedTheme] || {};
hasOldTheme = !$.isEmptyObject(oldtheme);
oldremove = hasOldTheme ? [ oldtheme.sortNone, oldtheme.sortDesc, oldtheme.sortAsc, oldtheme.active ].join( ' ' ) : '';
oldIconRmv = hasOldTheme ? [ oldtheme.iconSortNone, oldtheme.iconSortDesc, oldtheme.iconSortAsc ].join( ' ' ) : '';
if (hasOldTheme) {
wo.zebra[0] = $.trim( ' ' + wo.zebra[0].replace(' ' + oldtheme.even, '') );
wo.zebra[1] = $.trim( ' ' + wo.zebra[1].replace(' ' + oldtheme.odd, '') );
c.$tbodies.children().removeClass( [oldtheme.even, oldtheme.odd].join(' ') );
}
// update zebra stripes
if (themes.even) { wo.zebra[0] += ' ' + themes.even; }
if (themes.odd) { wo.zebra[1] += ' ' + themes.odd; }
// add caption style
$table.children('caption')
.removeClass(oldtheme.caption || '')
.addClass(themes.caption);
// add table/footer class names
$tfoot = $table
// remove other selected themes
.removeClass( (c.appliedTheme ? 'tablesorter-' + (c.appliedTheme || '') : '') + ' ' + (oldtheme.table || '') )
.addClass('tablesorter-' + theme + ' ' + (themes.table || '')) // add theme widget class name
.children('tfoot');
c.appliedTheme = c.theme;
if ($tfoot.length) {
$tfoot
// if oldtheme.footerRow or oldtheme.footerCells are undefined, all class names are removed
.children('tr').removeClass(oldtheme.footerRow || '').addClass(themes.footerRow)
.children('th, td').removeClass(oldtheme.footerCells || '').addClass(themes.footerCells);
}
// update header classes
$headers
.removeClass( (hasOldTheme ? [oldtheme.header, oldtheme.hover, oldremove].join(' ') : '') || '' )
.addClass(themes.header)
.not('.sorter-false')
.unbind('mouseenter.tsuitheme mouseleave.tsuitheme')
.bind('mouseenter.tsuitheme mouseleave.tsuitheme', function(event) {
// toggleClass with switch added in jQuery 1.3
$(this)[ event.type === 'mouseenter' ? 'addClass' : 'removeClass' ](themes.hover || '');
});
$headers.each(function(){
var $this = $(this);
if (!$this.find('.' + ts.css.wrapper).length) {
// Firefox needs this inner div to position the icon & resizer correctly
$this.wrapInner('<div class="' + ts.css.wrapper + '" style="position:relative;height:100%;width:100%"></div>');
ts.addWidget({
id: 'uitheme',
priority: 10,
format: function(table, c, wo) {
var i, hdr, icon, time, $header, $icon, $tfoot, $h, oldtheme, oldremove, oldIconRmv, hasOldTheme,
themesAll = ts.themes,
$table = c.$table.add( $( c.namespace + '_extra_table' ) ),
$headers = c.$headers.add( $( c.namespace + '_extra_headers' ) ),
theme = c.theme || 'jui',
themes = themesAll[theme] || {},
remove = $.trim( [ themes.sortNone, themes.sortDesc, themes.sortAsc, themes.active ].join( ' ' ) ),
iconRmv = $.trim( [ themes.iconSortNone, themes.iconSortDesc, themes.iconSortAsc ].join( ' ' ) );
if (c.debug) { time = new Date(); }
// initialization code - run once
if (!$table.hasClass('tablesorter-' + theme) || c.theme !== c.appliedTheme || !wo.uitheme_applied) {
wo.uitheme_applied = true;
oldtheme = themesAll[c.appliedTheme] || {};
hasOldTheme = !$.isEmptyObject(oldtheme);
oldremove = hasOldTheme ? [ oldtheme.sortNone, oldtheme.sortDesc, oldtheme.sortAsc, oldtheme.active ].join( ' ' ) : '';
oldIconRmv = hasOldTheme ? [ oldtheme.iconSortNone, oldtheme.iconSortDesc, oldtheme.iconSortAsc ].join( ' ' ) : '';
if (hasOldTheme) {
wo.zebra[0] = $.trim( ' ' + wo.zebra[0].replace(' ' + oldtheme.even, '') );
wo.zebra[1] = $.trim( ' ' + wo.zebra[1].replace(' ' + oldtheme.odd, '') );
c.$tbodies.children().removeClass( [ oldtheme.even, oldtheme.odd ].join(' ') );
}
});
if (c.cssIcon) {
// if c.cssIcon is '', then no <i> is added to the header
// update zebra stripes
if (themes.even) { wo.zebra[0] += ' ' + themes.even; }
if (themes.odd) { wo.zebra[1] += ' ' + themes.odd; }
// add caption style
$table.children('caption')
.removeClass(oldtheme.caption || '')
.addClass(themes.caption);
// add table/footer class names
$tfoot = $table
// remove other selected themes
.removeClass( (c.appliedTheme ? 'tablesorter-' + (c.appliedTheme || '') : '') + ' ' + (oldtheme.table || '') )
.addClass('tablesorter-' + theme + ' ' + (themes.table || '')) // add theme widget class name
.children('tfoot');
c.appliedTheme = c.theme;
if ($tfoot.length) {
$tfoot
// if oldtheme.footerRow or oldtheme.footerCells are undefined, all class names are removed
.children('tr').removeClass(oldtheme.footerRow || '').addClass(themes.footerRow)
.children('th, td').removeClass(oldtheme.footerCells || '').addClass(themes.footerCells);
}
// update header classes
$headers
.find('.' + ts.css.icon)
.removeClass(hasOldTheme ? [oldtheme.icons, oldIconRmv].join(' ') : '')
.addClass(themes.icons || '');
}
if ($table.hasClass('hasFilters')) {
$table.children('thead').children('.' + ts.css.filterRow)
.removeClass(hasOldTheme ? oldtheme.filterRow || '' : '')
.addClass(themes.filterRow || '');
}
}
for (i = 0; i < c.columns; i++) {
$header = c.$headers
.add($(c.namespace + '_extra_headers'))
.not('.sorter-false')
.filter('[data-column="' + i + '"]');
$icon = (ts.css.icon) ? $header.find('.' + ts.css.icon) : $();
$h = $headers.not('.sorter-false').filter('[data-column="' + i + '"]:last');
if ($h.length) {
$header.removeClass(remove);
$icon.removeClass(iconRmv);
if ($h[0].sortDisabled) {
// no sort arrows for disabled columns!
$icon.removeClass(themes.icons || '');
} else {
hdr = themes.sortNone;
icon = themes.iconSortNone;
if ($h.hasClass(ts.css.sortAsc)) {
hdr = [themes.sortAsc, themes.active].join(' ');
icon = themes.iconSortAsc;
} else if ($h.hasClass(ts.css.sortDesc)) {
hdr = [themes.sortDesc, themes.active].join(' ');
icon = themes.iconSortDesc;
.removeClass( (hasOldTheme ? [ oldtheme.header, oldtheme.hover, oldremove ].join(' ') : '') || '' )
.addClass(themes.header)
.not('.sorter-false')
.unbind('mouseenter.tsuitheme mouseleave.tsuitheme')
.bind('mouseenter.tsuitheme mouseleave.tsuitheme', function(event) {
// toggleClass with switch added in jQuery 1.3
$(this)[ event.type === 'mouseenter' ? 'addClass' : 'removeClass' ](themes.hover || '');
});
$headers.each(function(){
var $this = $(this);
if (!$this.find('.' + ts.css.wrapper).length) {
// Firefox needs this inner div to position the icon & resizer correctly
$this.wrapInner('<div class="' + ts.css.wrapper + '" style="position:relative;height:100%;width:100%"></div>');
}
$header.addClass(hdr);
$icon.addClass(icon || '');
});
if (c.cssIcon) {
// if c.cssIcon is '', then no <i> is added to the header
$headers
.find('.' + ts.css.icon)
.removeClass(hasOldTheme ? [ oldtheme.icons, oldIconRmv ].join(' ') : '')
.addClass(themes.icons || '');
}
if ($table.hasClass('hasFilters')) {
$table.children('thead').children('.' + ts.css.filterRow)
.removeClass(hasOldTheme ? oldtheme.filterRow || '' : '')
.addClass(themes.filterRow || '');
}
}
for (i = 0; i < c.columns; i++) {
$header = c.$headers
.add($(c.namespace + '_extra_headers'))
.not('.sorter-false')
.filter('[data-column="' + i + '"]');
$icon = (ts.css.icon) ? $header.find('.' + ts.css.icon) : $();
$h = $headers.not('.sorter-false').filter('[data-column="' + i + '"]:last');
if ($h.length) {
$header.removeClass(remove);
$icon.removeClass(iconRmv);
if ($h[0].sortDisabled) {
// no sort arrows for disabled columns!
$icon.removeClass(themes.icons || '');
} else {
hdr = themes.sortNone;
icon = themes.iconSortNone;
if ($h.hasClass(ts.css.sortAsc)) {
hdr = [ themes.sortAsc, themes.active ].join(' ');
icon = themes.iconSortAsc;
} else if ($h.hasClass(ts.css.sortDesc)) {
hdr = [ themes.sortDesc, themes.active ].join(' ');
icon = themes.iconSortDesc;
}
$header.addClass(hdr);
$icon.addClass(icon || '');
}
}
}
if (c.debug) {
ts.benchmark('Applying ' + theme + ' theme', time);
}
},
remove: function(table, c, wo, refreshing) {
if (!wo.uitheme_applied) { return; }
var $table = c.$table,
theme = c.appliedTheme || 'jui',
themes = ts.themes[ theme ] || ts.themes.jui,
$headers = $table.children('thead').children(),
remove = themes.sortNone + ' ' + themes.sortDesc + ' ' + themes.sortAsc,
iconRmv = themes.iconSortNone + ' ' + themes.iconSortDesc + ' ' + themes.iconSortAsc;
$table.removeClass('tablesorter-' + theme + ' ' + themes.table);
wo.uitheme_applied = false;
if (refreshing) { return; }
$table.find(ts.css.header).removeClass(themes.header);
$headers
.unbind('mouseenter.tsuitheme mouseleave.tsuitheme') // remove hover
.removeClass(themes.hover + ' ' + remove + ' ' + themes.active)
.filter('.' + ts.css.filterRow)
.removeClass(themes.filterRow);
$headers.find('.' + ts.css.icon).removeClass(themes.icons + ' ' + iconRmv);
}
if (c.debug) {
ts.benchmark("Applying " + theme + " theme", time);
}
},
remove: function(table, c, wo, refreshing) {
if (!wo.uitheme_applied) { return; }
var $table = c.$table,
theme = c.appliedTheme || 'jui',
themes = ts.themes[ theme ] || ts.themes.jui,
$headers = $table.children('thead').children(),
remove = themes.sortNone + ' ' + themes.sortDesc + ' ' + themes.sortAsc,
iconRmv = themes.iconSortNone + ' ' + themes.iconSortDesc + ' ' + themes.iconSortAsc;
$table.removeClass('tablesorter-' + theme + ' ' + themes.table);
wo.uitheme_applied = false;
if (refreshing) { return; }
$table.find(ts.css.header).removeClass(themes.header);
$headers
.unbind('mouseenter.tsuitheme mouseleave.tsuitheme') // remove hover
.removeClass(themes.hover + ' ' + remove + ' ' + themes.active)
.filter('.' + ts.css.filterRow)
.removeClass(themes.filterRow);
$headers.find('.' + ts.css.icon).removeClass(themes.icons + ' ' + iconRmv);
}
});
});
})(jQuery);

0
jscs.errors.txt Normal file
View File

View File

@ -75,6 +75,7 @@
"grunt-contrib-qunit": "^0.5.2",
"grunt-contrib-uglify": "^0.7.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-jscs": "^1.8.0",
"grunt-string-replace": "^1.0.0"
}
}