| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808 | 
							- /*
 
-  * 
 
-  * TableSorter 2.0 - Client-side table sorting with ease!
 
-  * Version 2.0
 
-  * @requires jQuery v1.1.3
 
-  * 
 
-  * Copyright (c) 2007 Christian Bach
 
-  * Examples and docs at: http://tablesorter.com
 
-  * 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.
 
-  *
 
-  * @example $('#table').tablesorter({ sortList:[[0,0],[1,0]] });
 
-  * @desc Create a tablesorter interface and sort on the first and secound column in ascending order.
 
-  * 
 
-  * @example $('#table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } });
 
-  * @desc Create a tablesorter interface and disableing the first and secound column headers.
 
-  * 
 
-  * @example $('#table').tablesorter({ 0: {sorter:"integer"}, 1: {sorter:"currency"} });
 
-  * @desc Create a tablesorter interface and set a column parser for the first and secound column.
 
-  * 
 
-  * 
 
-  * @param Object settings An object literal containing key/value pairs to provide optional settings.
 
-  * 
 
-  * @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 String textExtraction (optional) 	A string of the text-extraction method to use. 
 
-  * 												For complex html structures inside td cell set this option to "complex", 
 
-  * 												on large tables the complex option can be slow. 
 
-  * 												Default value: "simple"
 
-  * 
 
-  * @option Object headers (optional) 			An array containing the forces sorting rules. 
 
-  * 												This option let's you specify a default sorting rule. 
 
-  * 												Default value: null
 
-  * 
 
-  * @option Array sortList (optional) 			An array containing the forces sorting rules. 
 
-  * 												This option let's you specify a default sorting rule. 
 
-  * 												Default value: null
 
-  * 
 
-  * @option Array sortForce (optional) 			An array containing the forces sorting rules. 
 
-  * 												This option let's you specify a default sorting rule. 
 
-  * 												Default value: null
 
-  *  
 
-  * 
 
-  * @option Boolean widthFixed (optional) 		Boolean flag indicating if tablesorter should apply fixed widths to the table columns.
 
-  * 												This is usefull when using the pager companion plugin.
 
-  * 												This options requires the dimension jquery plugin.
 
-  * 												Default value: false
 
-  *
 
-  * @option Boolean cancelSelection (optional) 	Boolean flag indicating if tablesorter should cancel selection of the table headers text.
 
-  * 												Default value: true
 
-  * 
 
-  * @type jQuery
 
-  *
 
-  * @name tablesorter
 
-  * 
 
-  * @cat Plugins/Tablesorter
 
-  * 
 
-  * @author Christian Bach/christian.bach@polyester.se
 
-  */
 
- (function($) {
 
- 	$.extend({
 
- 		tablesorter: new function() {
 
- 			
 
- 			var parsers = [], widgets = [];
 
- 			
 
- 			this.defaults = {
 
- 				cssHeader: "header",
 
- 				cssAsc: "headerSortUp",
 
- 				cssDesc: "headerSortDown",
 
- 				sortInitialOrder: "asc",
 
- 				sortMultiSortKey: "shiftKey",
 
- 				sortForce: null,
 
- 				textExtraction: "simple",
 
- 				parsers: {}, 
 
- 				widgets: [],		
 
- 				widgetZebra: {css: ["even","odd"]},
 
- 				headers: {},
 
- 				widthFixed: false,
 
- 				cancelSelection: true,
 
- 				sortList: [],
 
- 				headerList: [],
 
- 				dateFormat: "us",
 
- 				debug: false
 
- 			};
 
- 			
 
- 			/* debuging utils */
 
- 			function benchmark(label,stamp) {
 
- 				log(label + "," + (new Date().getTime() - stamp.getTime()) + "ms");
 
- 			}
 
- 			
 
- 			function log(s) {
 
- 				if (typeof console != "undefined" && typeof console.debug != "undefined") {
 
- 					console.log(s);
 
- 				} else {
 
- 					alert(s);
 
- 				}
 
- 			}
 
- 						
 
- 			/* parsers utils */
 
- 			function buildParserCache(table,$headers) {
 
- 				
 
- 				if(table.config.debug) { var parsersDebug = ""; }
 
- 				
 
- 				var list = [], cells = table.tBodies[0].rows[0].cells, l = cells.length;
 
- 				
 
- 				for (var i=0;i < l; i++) {
 
- 					var p = false;
 
- 					
 
- 					if($.meta && ($($headers[i]).data() && $($headers[i]).data().sorter)  ) {
 
- 					
 
- 						p = getParserById($($headers[i]).data().sorter);	
 
- 					
 
- 					} else if((table.config.headers[i] && table.config.headers[i].sorter)) {
 
- 						p = getParserById(table.config.headers[i].sorter);
 
- 					}
 
- 					if(!p) {
 
- 						p = detectParserForColumn(table.config,cells[i]);
 
- 					}
 
- 					if(table.config.debug) { parsersDebug += "column:" + i + " parser:" +p.id + "\n"; }
 
- 					list.push(p);
 
- 				}
 
- 				if(table.config.debug) { log(parsersDebug); }
 
- 				return list;
 
- 			};
 
- 			
 
- 			function detectParserForColumn(config,node) {
 
- 				var l = parsers.length;
 
- 				for(var i=1; i < l; i++) {
 
- 					if(parsers[i].is($.trim(getElementText(config,node)))) {
 
- 						return parsers[i];
 
- 					}
 
- 				}
 
- 				
 
- 				// 0 is always the generic parser (text)
 
- 				return parsers[0];
 
- 			}
 
- 			
 
- 			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].cells.length,
 
- 					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 = [];
 
- 					
 
- 						cache.row.push($(c));
 
- 						
 
- 						for(var j=0; j < totalCells; ++j) {
 
- 							cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j]));	
 
- 						}
 
- 												
 
- 						cols.push(i); // 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) {
 
- 				
 
- 				if(!node) return "";
 
- 								
 
- 				var t = "";
 
- 				
 
- 				
 
- 				if(typeof(config.textExtraction) == "function") {
 
- 					t = config.textExtraction(node);
 
- 				} else if(config.textExtraction == "complex") { 
 
- 					t = $(node).text();
 
- 				} else {
 
- 					if(node.childNodes[0] && node.childNodes[0].hasChildNodes()) {
 
- 						t = node.childNodes[0].innerHTML;
 
- 					} else {
 
- 						t = node.innerHTML;
 
- 					}
 
- 				}
 
- 				return t;
 
- 			}
 
- 			
 
- 			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 = $("tbody:first",table).empty();
 
- 					rows = [];
 
- 				
 
- 				for (var i=0;i < totalRows; i++) {
 
- 					 	rows.push(r[n[i][checkCell]]);
 
- 						if(table.config.appender == null) {
 
- 							tableBody.append(r[n[i][checkCell]]);
 
- 						}
 
- 				}	
 
- 				if(table.config.appender != null) {
 
- 					table.config.appender(table,rows);	
 
- 				}
 
- 				
 
- 				rows = null;
 
- 				
 
- 				//apply table widgets
 
- 				applyWidget(table);
 
- 				
 
- 				if(table.config.debug) { benchmark("Rebuilt table:", appendTime); }
 
- 			
 
- 			};
 
- 			
 
- 			function buildHeaders(table) {
 
- 				
 
- 				if(table.config.debug) { var time = new Date(); }
 
- 				
 
- 				var meta = ($.meta) ? true : false, tableHeadersRows = [];
 
- 			
 
- 				for(var i = 0; i < table.tHead.rows.length; i++) { tableHeadersRows[i]=0; };
 
- 				
 
- 				$tableHeaders = $(checkCellColSpan(table, tableHeadersRows, 0,table.tHead.rows[0].cells.length));
 
- 		
 
- 				$tableHeaders.each(function(index) {
 
- 							
 
- 					this.count = 0;
 
- 					this.column = index;
 
- 					this.order = formatSortingOrder(table.config.sortInitialOrder);
 
- 					
 
- 					if(checkHeaderMetadata(this) || checkHeaderOptions(table,index)) this.sortDisabled = true;
 
- 					
 
- 					if(!this.sortDisabled) {
 
- 						$(this).addClass(table.config.cssHeader);
 
- 					}
 
- 					
 
- 					// add cell to headerList
 
- 					table.config.headerList[index]= this;
 
- 				});
 
- 				
 
- 				if(table.config.debug) { benchmark("Built headers:", time); log($tableHeaders); }
 
- 				
 
- 				return $tableHeaders;
 
- 				
 
- 			};
 
- 						
 
- 		   	function checkCellColSpan(table, headerArr, row) {
 
-                 var arr = [], r = table.tHead.rows, c = r[row].cells;
 
- 				
 
- 				for(var i=headerArr[row]; i < c.length; i++) {
 
- 					var cell = c[i];
 
- 					
 
- 					if ( cell.colSpan > 1) { 
 
- 						arr = arr.concat(checkCellColSpan(table, headerArr,row+cell.rowSpan));
 
- 					} else  {
 
- 						if(table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row+1])) {
 
- 							arr.push(cell);
 
- 						}
 
- 						headerArr[row] = (i+row);
 
- 					}
 
- 				}
 
- 				return arr;
 
- 			};
 
- 			
 
- 			function checkHeaderMetadata(cell) {
 
- 				if(($.meta) && ($(cell).data().sorter === false)) { return true; };
 
- 				return false;
 
- 			}
 
- 			
 
- 			function checkHeaderOptions(table,i) {	
 
- 				if((table.config.headers[i]) && (table.config.headers[i].sorter === false)) { return true; };
 
- 				return false;
 
- 			}
 
- 			
 
- 			function applyWidget(table) {
 
- 				var c = table.config.widgets;
 
- 				var l = c.length;
 
- 				for(var i=0; i < l; i++) {
 
- 					
 
- 					getWidgetById(c[i]).format(table);
 
- 				}
 
- 				
 
- 			}
 
- 			
 
- 			function getWidgetById(name) {
 
- 				var l = widgets.length;
 
- 				for(var i=0; i < l; i++) {
 
- 					if(widgets[i].id.toLowerCase() == name.toLowerCase() ) {
 
- 						return widgets[i]; 
 
- 					}
 
- 				}
 
- 			};
 
- 			
 
- 			function formatSortingOrder(v) {
 
- 				
 
- 				if(typeof(v) != "Number") {
 
- 					i = (v.toLowerCase() == "desc") ? 1 : 0;
 
- 				} else {
 
- 					i = (v == (0 || 1)) ? v : 0;
 
- 				}
 
- 				return i;
 
- 			}
 
- 			
 
- 			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 fixColumnWidth(table,$headers) {
 
- 				var c = table.config;
 
- 				if(c.widthFixed) {
 
- 					var colgroup = $('<colgroup>');
 
- 					$("tbody:first tr:first td",table).each(function() {
 
- 						
 
- 						colgroup.append($('<col>').css('width',$(this).width()));
 
- 					
 
- 					});
 
- 					$(table).prepend(colgroup);
 
- 				};
 
- 			}
 
- 			
 
- 			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;
 
- 					
 
- 				for(var i=0; i < l; i++) {
 
- 					
 
- 					var c = sortList[i][0];
 
- 					var order = sortList[i][1];
 
- 					var s = (getCachedSortType(table.config.parsers,c) == "text") ? ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? "sortNumeric" : "sortNumericDesc");
 
- 					
 
- 					var e = "e" + i;
 
- 					
 
- 					dynamicExp += "var " + e + " = " + s + "(a[" + c + "],b[" + c + "]); ";
 
- 					dynamicExp += "if(" + e + ") { return " + e + "; } ";
 
- 					dynamicExp += "else { ";
 
- 				}
 
- 					
 
- 				for(var i=0; i < l; i++) {
 
- 					dynamicExp += "}; ";
 
- 				}
 
- 				
 
- 				dynamicExp += "return 0; ";	
 
- 				dynamicExp += "}; ";	
 
- 				
 
- 				eval(dynamicExp);
 
- 				
 
- 				cache.normalized.sort(sortWrapper);
 
- 				
 
- 				if(table.config.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order+ " time:", sortTime); }
 
- 				
 
- 				return cache;
 
- 			};
 
- 			
 
- 			function sortText(a,b) {
 
- 				return ((a < b) ? -1 : ((a > b) ? 1 : 0));
 
- 			};
 
- 			
 
- 			function sortTextDesc(a,b) {
 
- 				return ((b < a) ? -1 : ((b > a) ? 1 : 0));
 
- 			};	
 
- 			
 
- 	 		function sortNumeric(a,b) {
 
- 				return a-b;
 
- 			};
 
- 			
 
- 			function sortNumericDesc(a,b) {
 
- 				return b-a;
 
- 			};
 
- 			
 
- 			function getCachedSortType(parsers,i) {
 
- 				return parsers[i].type;
 
- 			};
 
- 			
 
- 			/* public methods */
 
- 			this.construct = function(settings) {
 
- 				return this.each(function() {
 
- 					
 
- 					
 
- 					
 
- 					
 
- 					var $this, $document,$headers, cache, config, shiftDown = 0, sortOrder;
 
- 					
 
- 					this.config = {};
 
- 					
 
- 					config = $.extend(this.config, $.tablesorter.defaults, settings);
 
- 					
 
- 					if(!this.tHead || !this.tBodies) return true;
 
- 					
 
- 					// store common expression for speed					
 
- 					$this = $(this);
 
- 					
 
- 					// build headers
 
- 					$headers = buildHeaders(this);
 
- 					
 
- 					// 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];
 
- 					
 
- 					// fixate columns if the users supplies the fixedWidth option
 
- 					fixColumnWidth(this);
 
- 					
 
- 					// apply event handling to headers
 
- 					// this is to big, perhaps break it out?
 
- 					$headers.click(function(e) {
 
- 						if(!this.sortDisabled) {
 
- 							// 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;
 
- 							
 
- 							
 
- 							
 
- 							// user only whants to sort on one column
 
- 							if(!e[config.sortMultiSortKey]) {
 
- 								
 
- 								// flush the sort list
 
- 								config.sortList = [];
 
- 								
 
- 								if(config.sortForce != null) {
 
- 									var a = config.sortForce; 
 
- 									for(var j=0; j < a.length; j++) { 	
 
- 										config.sortList.push(a[j]);	
 
- 									}
 
- 								}
 
- 								
 
- 								// 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]);
 
- 								}
 
- 							};
 
- 							
 
- 							//set css for headers
 
- 							setHeadersCss($this[0],$headers,config.sortList,sortCSS);
 
- 							
 
- 							// sort the table and append it to the dom
 
- 							appendToTable($this[0],multisort($this[0],config.sortList,cache));
 
- 							
 
- 							// stop normal event by returning false
 
- 							return false;
 
- 						}
 
- 					// cancel selection	
 
- 					}).mousedown(function() {
 
- 						if(config.cancelSelection) {
 
- 							this.onselectstart = function() {return false};
 
- 							//alert(this.onselectstart);
 
- 							return false;
 
- 						}
 
- 					});
 
- 					
 
- 					// apply easy methods that trigger binded events
 
- 					$this.bind("update",function() {
 
- 						
 
- 						// rebuild the cache map
 
- 						cache = buildCache(this);
 
- 						
 
- 					}).bind("sorton",function(e,list) {
 
- 						
 
- 						// update and store the sortlist
 
- 						var sortList = config.sortList = list;
 
- 						
 
- 						// 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);
 
- 					
 
- 					}).bind("applyWidgetId",function(e,id) {
 
- 						
 
- 						getWidgetById(id).format(this);
 
- 						
 
- 					});
 
- 					
 
- 					if($.meta && ($(this).data() && $(this).data().sortlist)) {
 
- 						config.sortList = $(this).data().sortlist;
 
- 					}
 
- 					// if user has supplied a sort list to constructor.
 
- 					if(config.sortList.length > 0) {
 
- 						$this.trigger("sorton",[config.sortList]);	
 
- 					}
 
- 					
 
- 					// apply widgets
 
- 					applyWidget(this);
 
- 				});
 
- 			};
 
- 			
 
- 			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.addWidget = function(widget) {
 
- 				widgets.push(widget);
 
- 			};
 
- 			
 
- 			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;
 
- 			};
 
- 			
 
- 		}
 
- 	});
 
- 	
 
- 	// extend plugin scope
 
- 	$.fn.extend({
 
-         tablesorter: $.tablesorter.construct
 
- 	});
 
- 	
 
- 	// add default parsers
 
- 	$.tablesorter.addParser({
 
- 		id: "text",
 
- 		is: function(s) {
 
- 			return true;
 
- 		},
 
- 		format: function(s) {
 
- 			return $.trim(s.toLowerCase());
 
- 		},
 
- 		type: "text"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "integer",
 
- 		is: function(s) {
 
- 			return s.match(new RegExp(/^\d+$/));
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatInt(s);
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "currency",
 
- 		is: function(s) {
 
- 			return /^[£$€?.]/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),""));
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "integer",
 
- 		is: function(s) {
 
- 			return /^\d+$/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatFloat(s);
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "floating",
 
- 		is: function(s) {
 
- 			return s.match(new RegExp(/^(\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?$/));
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatFloat(s.replace(new RegExp(/,/),""));
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "ipAddress",
 
- 		is: function(s) {
 
- 			return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			var a = s.split(".");
 
- 			var r = "";
 
- 			for (var i = 0, item; item = a[i]; i++) {
 
- 			   if(item.length == 2) {
 
- 					r += "0" + item;
 
- 			   } else {
 
- 					r += item;
 
- 			   }
 
- 			}
 
- 			return $.tablesorter.formatFloat(s);
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "url",
 
- 		is: function(s) {
 
- 			return /^(https?|ftp|file):\/\/$/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),''));
 
- 		},
 
- 		type: "text"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "isoDate",
 
- 		is: function(s) {
 
- 			return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(new RegExp(/-/g),"/")).getTime() : "0");
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "percent",
 
- 		is: function(s) {
 
- 			return /^\d{1,3}%$/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),""));
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "usLongDate",
 
- 		is: function(s) {
 
- 			return /^[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)))$/.test(s);
 
- 		},
 
- 		format: function(s) {
 
- 			return $.tablesorter.formatFloat(new Date(s).getTime());
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 		id: "shortDate",
 
- 		is: function(s) {
 
- 			return /\d{1,2}[\/-]\d{1,2}[\/-]\d{2,4}/.test(s);
 
- 		},
 
- 		format: function(s,table) {
 
- 			var c = table.config;
 
- 			s = s.replace(new RegExp(/-/g),"/");
 
- 			if(c.dateFormat == "us") {
 
- 				/** reformat the string in ISO format */
 
- 				s = s.replace(new RegExp(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{4})/), "$3/$1/$2");
 
- 			} else if(c.dateFormat == "uk") {
 
- 				/** reformat the string in ISO format */
 
- 				s = s.replace(new RegExp(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{4})/), "$3/$2/$1");
 
- 			} else if(c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") {
 
- 				s = s.replace(new RegExp(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2})/), "$1/$2/$3");	
 
- 			}
 
- 			return $.tablesorter.formatFloat(new Date(s).getTime());
 
- 		},
 
- 		type: "numeric"
 
- 	});
 
- 	
 
- 	$.tablesorter.addParser({
 
- 	    id: "time",
 
- 	    is: function(s) {
 
- 	        return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);
 
- 	    },
 
- 	    format: function(s) {
 
- 	        return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime());
 
- 	    },
 
- 	  type: "numeric"
 
- 	});
 
- 	
 
- 	
 
- 	$.tablesorter.addParser({
 
- 	    id: "metadata",
 
- 	    is: function(s) {
 
- 	        return false;
 
- 	    },
 
- 	    format: function(s,table,cell) {
 
- 			var c = table.config, p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName;
 
- 	        return $(cell).data()[p];
 
- 	    },
 
- 	  type: "numeric"
 
- 	});
 
- 	
 
- 	// add default widgets
 
- 	$.tablesorter.addWidget({
 
- 		id: "zebra",
 
- 		format: function(table) {
 
- 			$("> tbody:first/tr:visible:even",table).removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0]);
 
- 			$("> tbody:first/tr:visible:odd",table).removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]);
 
- 		}
 
- 	});
 
- 	
 
- })(jQuery);
 
 
  |