mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Build: Add jscs checking & fix style issues
Thanks @Herst!
This commit is contained in:
parent
bd296c844f
commit
75de112ef6
65
.jscsrc
Normal file
65
.jscsrc
Normal 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": "'"
|
||||
}
|
||||
}
|
23
Gruntfile.js
23
Gruntfile.js
@ -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',
|
||||
|
@ -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);
|
||||
|
5193
dist/js/jquery.tablesorter.combined.js
vendored
5193
dist/js/jquery.tablesorter.combined.js
vendored
File diff suppressed because it is too large
Load Diff
6
dist/js/jquery.tablesorter.combined.min.js
vendored
6
dist/js/jquery.tablesorter.combined.min.js
vendored
File diff suppressed because one or more lines are too long
110
dist/js/jquery.tablesorter.js
vendored
110
dist/js/jquery.tablesorter.js
vendored
@ -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) {
|
||||
|
4
dist/js/jquery.tablesorter.min.js
vendored
4
dist/js/jquery.tablesorter.min.js
vendored
File diff suppressed because one or more lines are too long
5083
dist/js/jquery.tablesorter.widgets.js
vendored
5083
dist/js/jquery.tablesorter.widgets.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/js/jquery.tablesorter.widgets.min.js
vendored
2
dist/js/jquery.tablesorter.widgets.min.js
vendored
File diff suppressed because one or more lines are too long
@ -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);
|
2
dist/js/widgets/widget-resizable.min.js
vendored
2
dist/js/widgets/widget-resizable.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/js/widgets/widget-scroller.min.js
vendored
2
dist/js/widgets/widget-scroller.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -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
@ -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);
|
||||
|
@ -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})))?)?)?)?$/;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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/ */
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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/ */
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 ],
|
||||
|
@ -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 );
|
||||
|
@ -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, '');
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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);
|
@ -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,
|
||||
|
@ -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'
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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',
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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
@ -5,7 +5,7 @@
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global jQuery: false */
|
||||
;(function($){
|
||||
'use strict';
|
||||
'use strict';
|
||||
var ts = $.tablesorter;
|
||||
|
||||
ts.formatter = {
|
||||
|
@ -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);
|
||||
|
@ -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 : '',
|
||||
|
@ -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>'
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 );
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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 );
|
||||
|
@ -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);
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
0
jscs.errors.txt
Normal 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"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user