wiki.techinc.nl/resources/jquery/jquery.tablesorter.js

937 lines
27 KiB
JavaScript
Raw Normal View History

/*
*
* TableSorter for MediaWiki
*
* Written 2011 Leo Koppelkamm
* Based on tablesorter.com plugin, written (c) 2007 Christian Bach.
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
/**
*
* @description Create a sortable table with multi-column sorting capabilitys
*
* @example $( 'table' ).tablesorter();
* @desc Create a simple tablesorter interface.
*
* @option String cssHeader ( optional ) A string of the class name to be appended
* to sortable tr elements in the thead of the table. Default value:
* "header"
*
* @option String cssAsc ( optional ) A string of the class name to be appended to
* sortable tr elements in the thead on a ascending sort. Default value:
* "headerSortUp"
*
* @option String cssDesc ( optional ) A string of the class name to be appended
* to sortable tr elements in the thead on a descending sort. Default
* value: "headerSortDown"
*
* @option String sortInitialOrder ( optional ) A string of the inital sorting
* order can be asc or desc. Default value: "asc"
*
* @option String sortMultisortKey ( optional ) A string of the multi-column sort
* key. Default value: "shiftKey"
*
* @option Boolean sortLocaleCompare ( optional ) Boolean flag indicating whatever
* to use String.localeCampare method or not. Set to false.
*
* @option Boolean cancelSelection ( optional ) Boolean flag indicating if
* tablesorter should cancel selection of the table headers text.
* Default value: true
*
* @option Boolean debug ( optional ) Boolean flag indicating if tablesorter
* should display debuging information usefull for development.
*
* @type jQuery
*
* @name tablesorter
*
* @cat Plugins/Tablesorter
*
* @author Christian Bach/christian.bach@polyester.se
*/
( function ($) {
$.extend( {
tablesorter: new
function () {
var parsers = [];
this.defaults = {
cssHeader: "headerSort",
cssAsc: "headerSortUp",
cssDesc: "headerSortDown",
cssChildRow: "expand-child",
sortInitialOrder: "asc",
sortMultiSortKey: "shiftKey",
sortLocaleCompare: false,
parsers: {},
widgets: [],
headers: {},
cancelSelection: true,
sortList: [],
headerList: [],
selectorHeaders: 'thead tr:eq(0) th',
debug: false
};
/* debuging utils */
//
// function benchmark( s, d ) {
// alert( s + "," + ( new Date().getTime() - d.getTime() ) + "ms" );
// }
//
// this.benchmark = benchmark;
//
//
/* parsers utils */
function buildParserCache( table, $headers ) {
var rows = table.tBodies[0].rows;
if ( rows[0] ) {
var list = [],
cells = rows[0].cells,
l = cells.length;
for ( var i = 0; i < l; i++ ) {
if ( $headers.eq(i).is( '[class*="sort-"]' ) ) {
p = getParserById($headers.eq(i).attr('class').replace(/.*?sort-(.*?) .*/, '$1'));
} else {
p = detectParserForColumn( table, rows, -1, i );
}
// if ( table.config.debug ) {
// console.log( "column:" + i + " parser:" + p.id + "\n" );
// }
list.push(p);
}
}
return list;
}
function detectParserForColumn( table, rows, rowIndex, cellIndex ) {
var l = parsers.length,
node = false,
nodeValue = false,
keepLooking = true;
while ( nodeValue == '' && keepLooking ) {
rowIndex++;
if ( rows[rowIndex] ) {
node = getNodeFromRowAndCellIndex( rows, rowIndex, cellIndex );
nodeValue = trimAndGetNodeText( table.config, node );
// if ( table.config.debug ) {
// console.log( 'Checking if value was empty on row:' + rowIndex );
// }
} else {
keepLooking = false;
}
}
for ( var i = 1; i < l; i++ ) {
if ( parsers[i].is( nodeValue, table, node ) ) {
return parsers[i];
}
}
// 0 is always the generic parser ( text )
return parsers[0];
}
function getNodeFromRowAndCellIndex( rows, rowIndex, cellIndex ) {
return rows[rowIndex].cells[cellIndex];
}
function trimAndGetNodeText( config, node ) {
return $.trim( getElementText( config, node ) );
}
function getParserById( name ) {
var l = parsers.length;
for ( var i = 0; i < l; i++ ) {
if ( parsers[i].id.toLowerCase() == name.toLowerCase() ) {
return parsers[i];
}
}
return false;
}
/* utils */
function buildCache( table ) {
// if ( table.config.debug ) {
// var cacheTime = new Date();
// }
var totalRows = ( table.tBodies[0] && table.tBodies[0].rows.length ) || 0,
totalCells = ( table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length ) || 0,
parsers = table.config.parsers,
cache = {
row: [],
normalized: []
};
for ( var i = 0; i < totalRows; ++i ) {
// Add the table data to main data array
var c = $( table.tBodies[0].rows[i] ),
cols = [];
// if this is a child row, add it to the last row's children and
// continue to the next row
if ( c.hasClass( table.config.cssChildRow ) ) {
cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c);
// go to the next for loop
continue;
}
cache.row.push(c);
for ( var j = 0; j < totalCells; ++j ) {
cols.push( parsers[j].format( getElementText( table.config, c[0].cells[j] ), table, c[0].cells[j] ) );
}
cols.push( cache.normalized.length ); // add position for rowCache
cache.normalized.push( cols );
cols = null;
}
// if ( table.config.debug ) {
// benchmark( "Building cache for " + totalRows + " rows:", cacheTime );
// }
return cache;
}
function getElementText( config, node ) {
return $( node ).text();
}
function appendToTable( table, cache ) {
// if ( table.config.debug ) {
// var appendTime = new Date()
// }
var c = cache,
r = c.row,
n = c.normalized,
totalRows = n.length,
checkCell = (n[0].length - 1),
tableBody = $( table.tBodies[0] ),
fragment = document.createDocumentFragment();
for ( var i = 0; i < totalRows; i++ ) {
var pos = n[i][checkCell];
var l = r[pos].length;
for ( var j = 0; j < l; j++ ) {
fragment.appendChild( r[pos][j] );
}
}
tableBody[0].appendChild( fragment );
// if ( table.config.debug ) {
// benchmark( "Rebuilt table:", appendTime );
// }
}
function buildHeaders( table ) {
// if ( table.config.debug ) {
// var time = new Date();
// }
//var header_index = computeTableHeaderCellIndexes( table );
var realCellIndex = 0;
$tableHeaders = $( table.config.selectorHeaders, table ).each( function ( index ) {
//var normalIndex = allCells.index( this );
//var realCellIndex = 0;
this.column = realCellIndex;
var colspan = this.colspan;
colspan = colspan ? parseInt( colspan ) : 1;
realCellIndex += colspan;
//this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];
this.order = 0;
this.count = 0;
if ( $( this ).is( '.unsortable' ) ) this.sortDisabled = true;
if ( !this.sortDisabled ) {
var $th = $( this ).addClass( table.config.cssHeader );
//if ( table.config.onRenderHeader ) table.config.onRenderHeader.apply($th);
}
// add cell to headerList
table.config.headerList[index] = this;
} );
// if ( table.config.debug ) {
// benchmark( "Built headers:", time );
// console.log( $tableHeaders );
// }
//
return $tableHeaders;
}
// // from:
// // http://www.javascripttoolbox.com/lib/table/examples.php
// // http://www.javascripttoolbox.com/temp/table_cellindex.html
//
// function computeTableHeaderCellIndexes(t) {
// var matrix = [];
// var lookup = {};
// var thead = t.getElementsByTagName( 'THEAD' )[0];
// var trs = thead.getElementsByTagName( 'TR' );
//
// for ( var i = 0; i < trs.length; i++ ) {
// var cells = trs[i].cells;
// for ( var j = 0; j < cells.length; j++ ) {
// var c = cells[j];
//
// var rowIndex = c.parentNode.rowIndex;
// var cellId = rowIndex + "-" + c.cellIndex;
// var rowSpan = c.rowSpan || 1;
// var colSpan = c.colSpan || 1;
// var firstAvailCol;
// if ( typeof( matrix[rowIndex] ) == "undefined" ) {
// matrix[rowIndex] = [];
// }
// // Find first available column in the first row
// for ( var k = 0; k < matrix[rowIndex].length + 1; k++ ) {
// if ( typeof( matrix[rowIndex][k] ) == "undefined" ) {
// firstAvailCol = k;
// break;
// }
// }
// lookup[cellId] = firstAvailCol;
// for ( var k = rowIndex; k < rowIndex + rowSpan; k++ ) {
// if ( typeof( matrix[k] ) == "undefined" ) {
// matrix[k] = [];
// }
// var matrixrow = matrix[k];
// for ( var l = firstAvailCol; l < firstAvailCol + colSpan; l++ ) {
// matrixrow[l] = "x";
// }
// }
// }
// }
// return lookup;
// }
// function checkCellColSpan( table, rows, row ) {
// var arr = [],
// r = table.tHead.rows,
// c = r[row].cells;
//
// for ( var i = 0; i < c.length; i++ ) {
// var cell = c[i];
//
// if ( cell.colSpan > 1 ) {
// arr = arr.concat( checkCellColSpan( table, headerArr, row++ ) );
// } else {
// if ( table.tHead.length == 1 || ( cell.rowSpan > 1 || !r[row + 1] ) ) {
// arr.push( cell );
// }
// // headerArr[row] = ( i+row );
// }
// }
// return arr;
// }
//
// function checkHeaderOptions( table, i ) {
// if ( ( table.config.headers[i] ) && ( table.config.headers[i].sorter === false ) ) {
// return true;
// }
// return false;
// }
// function formatSortingOrder(v) {
// if ( typeof(v) != "Number" ) {
// return ( v.toLowerCase() == "desc" ) ? 1 : 0;
// } else {
// return ( v == 1 ) ? 1 : 0;
// }
// }
function isValueInArray( v, a ) {
var l = a.length;
for ( var i = 0; i < l; i++ ) {
if ( a[i][0] == v ) {
return true;
}
}
return false;
}
function setHeadersCss( table, $headers, list, css ) {
// remove all header information
$headers.removeClass( css[0] ).removeClass( css[1] );
var h = [];
$headers.each( function ( offset ) {
if ( !this.sortDisabled ) {
h[this.column] = $( this );
}
} );
var l = list.length;
for ( var i = 0; i < l; i++ ) {
h[list[i][0]].addClass( css[list[i][1]] );
}
}
// function updateHeaderSortCount( table, sortList ) {
// var c = table.config,
// l = sortList.length;
// for ( var i = 0; i < l; i++ ) {
// var s = sortList[i],
// o = c.headerList[s[0]];
// o.count = s[1];
// o.count++;
// }
// }
/* sorting methods */
function multisort( table, sortList, cache ) {
// if ( table.config.debug ) {
// var sortTime = new Date();
// }
var dynamicExp = "var sortWrapper = function(a,b) {",
l = sortList.length;
// TODO: inline functions.
for ( var i = 0; i < l; i++ ) {
var c = sortList[i][0];
var order = sortList[i][1];
var s = "";
if ( table.config.parsers[c].type == "text" ) {
if ( order == 0 ) {
s = makeSortFunction( "text", "asc", c );
} else {
s = makeSortFunction( "text", "desc", c );
}
} else {
if ( order == 0 ) {
s = makeSortFunction( "numeric", "asc", c );
} else {
s = makeSortFunction( "numeric", "desc", c );
}
}
var e = "e" + i;
dynamicExp += "var " + e + " = " + s; // + "(a[" + c + "],b[" + c + "]); ";
dynamicExp += "if(" + e + ") { return " + e + "; } ";
dynamicExp += "else { ";
}
// if value is the same keep original order
var orgOrderCol = cache.normalized[0].length - 1;
dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];";
for ( var i = 0; i < l; i++ ) {
dynamicExp += "}; ";
}
dynamicExp += "return 0; ";
dynamicExp += "}; ";
// if ( table.config.debug ) {
// benchmark( "Evaling expression:" + dynamicExp, new Date() );
// }
eval( dynamicExp );
cache.normalized.sort( sortWrapper );
// if ( table.config.debug ) {
// benchmark( "Sorting on " + sortList.toString() + " and dir " + order + " time:", sortTime );
// }
return cache;
}
function makeSortFunction( type, direction, index ) {
var a = "a[" + index + "]",
b = "b[" + index + "]";
if (type == 'text' && direction == 'asc') {
return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + a + " < " + b + ") ? -1 : 1 )));";
} else if (type == 'text' && direction == 'desc') {
return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + b + " < " + a + ") ? -1 : 1 )));";
} else if (type == 'numeric' && direction == 'asc') {
return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + a + " - " + b + "));";
} else if (type == 'numeric' && direction == 'desc') {
return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + b + " - " + a + "));";
}
}
function makeSortText(i) {
return "((a[" + i + "] < b[" + i + "]) ? -1 : ((a[" + i + "] > b[" + i + "]) ? 1 : 0));";
}
function makeSortTextDesc(i) {
return "((b[" + i + "] < a[" + i + "]) ? -1 : ((b[" + i + "] > a[" + i + "]) ? 1 : 0));";
}
function makeSortNumeric(i) {
return "a[" + i + "]-b[" + i + "];";
}
function makeSortNumericDesc(i) {
return "b[" + i + "]-a[" + i + "];";
}
function sortText( a, b ) {
if ( table.config.sortLocaleCompare ) return a.localeCompare(b);
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
}
function sortTextDesc( a, b ) {
if ( table.config.sortLocaleCompare ) return b.localeCompare(a);
return ((b < a) ? -1 : ((b > a) ? 1 : 0));
}
function sortNumeric( a, b ) {
return a - b;
}
function sortNumericDesc( a, b ) {
return b - a;
}
function buildTransformTable() {
var digits = '0123456789,.'.split('');
if ( typeof wgSeparatorTransformTable == 'undefined' || ( wgSeparatorTransformTable[0] == '' && wgDigitTransformTable[2] == '' ) ) {
ts.transformTable = false;
} else {
ts.transformTable = {};
// Unpack the transform table
var ascii = wgSeparatorTransformTable[0].split( "\t" ).concat( wgDigitTransformTable[0].split( "\t" ) );
var localised = wgSeparatorTransformTable[1].split( "\t" ).concat( wgDigitTransformTable[1].split( "\t" ) );
// Construct regex for number identification
for ( var i = 0; i < ascii.length; i++ ) {
ts.transformTable[localised[i]] = ascii[i];
digits.push( $.escapeRE( localised[i] ) );
}
}
var digitClass = '[' + digits.join( '', digits ) + ']';
// We allow a trailing percent sign, which we just strip. This works fine
// if percents and regular numbers aren't being mixed.
ts.numberRegex = new RegExp("^(" + "[-+\u2212]?[0-9][0-9,]*(\\.[0-9,]*)?(E[-+\u2212]?[0-9][0-9,]*)?" + // Fortran-style scientific
"|" + "[-+\u2212]?" + digitClass + "+%?" + // Generic localised
")$", "i");
}
function buildDateTable() {
var r = '';
ts.monthNames = [
[],
[]
];
ts.dateRegex = [];
for ( i = 1; i < 13; i++ ) {
ts.monthNames[0][i] = wgMonthNames[i].toLowerCase();
ts.monthNames[1][i] = wgMonthNamesShort[i].toLowerCase().replace( '.', '' );
r += $.escapeRE( ts.monthNames[0][i] ) + '|';
r += $.escapeRE( ts.monthNames[1][i] ) + '|';
}
//Remove trailing pipe
r = r.slice( 0, -1 );
//Build RegEx
//Any date formated with . , ' - or /
ts.dateRegex[0] = new RegExp(/^\s*\d{1,2}[\,\.\-\/'\s]*\d{1,2}[\,\.\-\/'\s]*\d{2,4}\s*?/i);
//Written Month name, dmy
ts.dateRegex[1] = new RegExp('^\\s*\\d{1,2}[\\,\\.\\-\\/\'\\s]*(' + r + ')' + '[\\,\\.\\-\\/\'\\s]*\\d{2,4}\\s*$', 'i');
//Written Month name, mdy
ts.dateRegex[2] = new RegExp('^\\s*(' + r + ')' + '[\\,\\.\\-\\/\'\\s]*\\d{1,2}[\\,\\.\\-\\/\'\\s]*\\d{2,4}\\s*$', 'i');
}
function buildCollationTable() {
if ( typeof tableSorterCollation == "object" ) {
ts.collationRegex = [];
//Build array of key names
for ( var key in tableSorterCollation ) {
if ( tableSorterCollation.hasOwnProperty(key) ) { //to be safe
ts.collationRegex.push(key);
}
}
ts.collationRegex = new RegExp( '[' + ts.collationRegex.join('') + ']', 'ig' );
}
}
function cacheRegexs() {
ts.rgx = {
IPAddress: [new RegExp(/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/)],
currency: [new RegExp(/^[£$€?.]/), new RegExp(/[£$€]/g)],
url: [new RegExp(/^(https?|ftp|file):\/\/$/), new RegExp(/(https?|ftp|file):\/\//)],
isoDate: [new RegExp(/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/)],
usLongDate: [new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)],
time: [new RegExp(/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/)]
};
} /* public methods */
this.construct = function ( settings ) {
return this.each( function () {
// if no thead or tbody quit.
if ( !this.tHead || !this.tBodies ) return;
// declare
var $this, $document, $headers, cache, config, shiftDown = 0,
sortOrder;
// new blank config object
this.config = {};
// merge and extend.
config = $.extend( this.config, $.tablesorter.defaults, settings );
// store common expression for speed
$this = $( this );
// save the settings where they read
$.data( this, "tablesorter", config );
// build headers
$headers = buildHeaders( this );
// Grab and process locale settings
buildTransformTable();
buildDateTable();
buildCollationTable();
//Precaching regexps can bring 10 fold
//performance improvements in some browsers
cacheRegexs();
// try to auto detect column type, and store in tables config
this.config.parsers = buildParserCache( this, $headers );
// build the cache for the tbody cells
cache = buildCache( this );
// get the css class names, could be done else where.
var sortCSS = [config.cssDesc, config.cssAsc];
// apply event handling to headers
// this is to big, perhaps break it out?
$headers.click(
function (e) {
//var clickTime= new Date();
var totalRows = ( $this[0].tBodies[0] && $this[0].tBodies[0].rows.length ) || 0;
if ( !this.sortDisabled && totalRows > 0 ) {
// Only call sortStart if sorting is
// enabled.
//$this.trigger( "sortStart" );
// store exp, for speed
var $cell = $( this );
// get current column index
var i = this.column;
// get current column sort order
this.order = this.count % 2;
this.count++;
// user only whants to sort on one
// column
if ( !e[config.sortMultiSortKey] ) {
// flush the sort list
config.sortList = [];
// add column to sort list
config.sortList.push( [i, this.order] );
// multi column sorting
} else {
// the user has clicked on an all
// ready sortet column.
if ( isValueInArray( i, config.sortList ) ) {
// revers the sorting direction
// for all tables.
for ( var j = 0; j < config.sortList.length; j++ ) {
var s = config.sortList[j],
o = config.headerList[s[0]];
if ( s[0] == i ) {
o.count = s[1];
o.count++;
s[1] = o.count % 2;
}
}
} else {
// add column to sort list array
config.sortList.push( [i, this.order] );
}
}
setTimeout( function () {
// set css for headers
setHeadersCss( $this[0], $headers, config.sortList, sortCSS );
appendToTable(
$this[0], multisort(
$this[0], config.sortList, cache ) );
//benchmark( "Sorting " + totalRows + " rows:", clickTime );
}, 1 );
// stop normal event by returning false
return false;
}
// cancel selection
} ).mousedown( function () {
if ( config.cancelSelection ) {
this.onselectstart = function () {
return false;
};
return false;
}
} );
// apply easy methods that trigger binded events
//Can't think of any use for these in a mw context
// $this.bind( "update", function () {
// var me = this;
// setTimeout( function () {
// // rebuild parsers.
// me.config.parsers = buildParserCache(
// me, $headers );
// // rebuild the cache map
// cache = buildCache(me);
// }, 1 );
// } ).bind( "updateCell", function ( e, cell ) {
// var config = this.config;
// // get position from the dom.
// var pos = [( cell.parentNode.rowIndex - 1 ), cell.cellIndex];
// // update cache
// cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format(
// getElementText( config, cell ), cell );
// } ).bind( "sorton", function ( e, list ) {
// $( this ).trigger( "sortStart" );
// config.sortList = list;
// // update and store the sortlist
// var sortList = config.sortList;
// // update header count index
// updateHeaderSortCount( this, sortList );
// // set css for headers
// setHeadersCss( this, $headers, sortList, sortCSS );
// // sort the table and append it to the dom
// appendToTable( this, multisort( this, sortList, cache ) );
// } ).bind( "appendCache", function () {
// appendToTable( this, cache );
// } );
} );
};
this.addParser = function ( parser ) {
var l = parsers.length,
a = true;
for ( var i = 0; i < l; i++ ) {
if ( parsers[i].id.toLowerCase() == parser.id.toLowerCase() ) {
a = false;
}
}
if (a) {
parsers.push( parser );
}
};
this.formatDigit = function (s) {
if ( ts.transformTable != false ) {
var out = '',
c;
for ( var p = 0; p < s.length; p++ ) {
c = s.charAt(p);
if ( c in ts.transformTable ) {
out += ts.transformTable[c];
} else {
out += c;
}
}
s = out;
}
var i = parseFloat( s.replace(/[, ]/g, '').replace( "\u2212", '-' ) );
return ( isNaN(i)) ? 0 : i;
};
this.formatFloat = function (s) {
var i = parseFloat(s);
return ( isNaN(i)) ? 0 : i;
};
this.formatInt = function (s) {
var i = parseInt(s);
return ( isNaN(i)) ? 0 : i;
};
this.clearTableBody = function ( table ) {
if ( $.browser.msie ) {
function empty() {
while ( this.firstChild )
this.removeChild( this.firstChild );
}
empty.apply( table.tBodies[0] );
} else {
table.tBodies[0].innerHTML = "";
}
};
}
} );
// extend plugin scope
$.fn.extend( {
tablesorter: $.tablesorter.construct
} );
// make shortcut
var ts = $.tablesorter;
// add default parsers
ts.addParser( {
id: "text",
is: function (s) {
return true;
},
format: function (s) {
s = $.trim( s.toLowerCase() );
if ( ts.collationRegex ) {
var tsc = tableSorterCollation;
s = s.replace( ts.collationRegex, function ( match ) {
var r = tsc[match] ? tsc[match] : tsc[match.toUpperCase()];
return r.toLowerCase();
} );
}
return s;
},
type: "text"
} );
ts.addParser( {
id: "IPAddress",
is: function (s) {
return ts.rgx.IPAddress[0].test(s);
},
format: function (s) {
var a = s.split("."),
r = "",
l = a.length;
for ( var i = 0; i < l; i++ ) {
var item = a[i];
if ( item.length == 2 ) {
r += "0" + item;
} else {
r += item;
}
}
return $.tablesorter.formatFloat(r);
},
type: "numeric"
} );
ts.addParser( {
id: "number",
is: function ( s, table ) {
return $.tablesorter.numberRegex.test( $.trim(s ));
},
format: function (s) {
return $.tablesorter.formatDigit(s);
},
type: "numeric"
} );
ts.addParser( {
id: "currency",
is: function (s) {
return ts.rgx.currency[0].test(s);
},
format: function (s) {
return $.tablesorter.formatDigit( s.replace( ts.rgx.currency[1], "" ) );
},
type: "numeric"
} );
ts.addParser( {
id: "url",
is: function (s) {
return ts.rgx.url[0].test(s);
},
format: function (s) {
return $.trim( s.replace( ts.rgx.url[1], '' ) );
},
type: "text"
} );
ts.addParser( {
id: "isoDate",
is: function (s) {
return ts.rgx.isoDate[0].test(s);
},
format: function (s) {
return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(
new RegExp(/-/g), "/")).getTime() : "0");
},
type: "numeric"
} );
ts.addParser( {
id: "usLongDate",
is: function (s) {
return ts.rgx.usLongDate[0].test(s);
},
format: function (s) {
return $.tablesorter.formatFloat( new Date(s).getTime() );
},
type: "numeric"
} );
ts.addParser( {
id: "date",
is: function (s) {
return ( ts.dateRegex[0].test(s) || ts.dateRegex[1].test(s) || ts.dateRegex[2].test(s ));
},
format: function ( s, table ) {
s = s.toLowerCase();
for ( i = 1, j = 0; i < 13 && j < 2; i++ ) {
s = s.replace( ts.monthNames[j][i], i );
if ( i == 12 ) {
j++;
i = 0;
}
}
s = s.replace(/[\-\.\,' ]/g, "/");
//Replace double slashes
s = s.replace(/\/\//g, "/");
s = s.replace(/\/\//g, "/");
s = s.split('/');
//Pad Month and Day
if ( s[0].length == 1 ) s[0] = "0" + s[0];
if ( s[1].length == 1 ) s[1] = "0" + s[1];
if ( !s[2] ) {
//Fix yearless dates
s[2] = 2000;
} else if ( ( y = parseInt( s[2] ) ) < 100 ) {
//Guestimate years without centuries
if ( y < 30 ) {
s[2] = 2000 + y;
} else {
s[2] = 1900 + y;
}
}
//Resort array depending on preferences
if ( wgDefaultDateFormat == "mdy" ) {
s.push( s.shift() );
s.push( s.shift() );
} else if ( wgDefaultDateFormat == "dmy" ) {
var d = s.shift();
s.push( s.shift() );
s.push(d);
}
return parseInt( s.join('') );
},
type: "numeric"
} );
ts.addParser( {
id: "time",
is: function (s) {
return ts.rgx.time[0].test(s);
},
format: function (s) {
return $.tablesorter.formatFloat( new Date( "2000/01/01 " + s ).getTime() );
},
type: "numeric"
} );
} )( jQuery );