diff options
author | Dan McGee <dan@archlinux.org> | 2012-10-21 15:43:27 +0200 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2012-10-21 15:43:27 +0200 |
commit | ca1d4faa531768515f48b6856fda13016e12c0d3 (patch) | |
tree | b6c9571da500b64d703b930805a134cc5d6bf365 | |
parent | 072b5b2a6baf2c014168e4fff1a1f2fb8f652e52 (diff) | |
download | archweb-ca1d4faa531768515f48b6856fda13016e12c0d3.tar.gz archweb-ca1d4faa531768515f48b6856fda13016e12c0d3.tar.xz |
Update tablesorter JS
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | main/templatetags/cdn.py | 2 | ||||
-rw-r--r-- | sitestatic/jquery.tablesorter-2.3.11.min.js | 6 | ||||
-rw-r--r-- | sitestatic/jquery.tablesorter-2.4.5.js (renamed from sitestatic/jquery.tablesorter-2.3.11.js) | 780 | ||||
-rw-r--r-- | sitestatic/jquery.tablesorter-2.4.5.min.js | 6 |
4 files changed, 473 insertions, 321 deletions
diff --git a/main/templatetags/cdn.py b/main/templatetags/cdn.py index b1c6581..f3ef9a1 100644 --- a/main/templatetags/cdn.py +++ b/main/templatetags/cdn.py @@ -20,7 +20,7 @@ def jquery(): @register.simple_tag def jquery_tablesorter(): - version = '2.3.11' + version = '2.4.5' filename = 'jquery.tablesorter-%s.min.js' % version link = staticfiles_storage.url(filename) return '<script type="text/javascript" src="%s"></script>' % link diff --git a/sitestatic/jquery.tablesorter-2.3.11.min.js b/sitestatic/jquery.tablesorter-2.3.11.min.js deleted file mode 100644 index 20f808f..0000000 --- a/sitestatic/jquery.tablesorter-2.3.11.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! -* TableSorter 2.3.11 - Client-side table sorting with ease! -* Minified using UglifyJS (http://jscompress.com/) -* Copyright (c) 2007 Christian Bach -*/ -!function($){$.extend({tablesorter:new function(){function log(a){if(typeof console!=="undefined"&&typeof console.log!=="undefined"){console.log(a)}else{alert(a)}}function benchmark(a,b){log(a+" ("+((new Date).getTime()-b.getTime())+"ms)")}function getElementText(a,b,c){if(!b){return""}var d=a.config,e=d.textExtraction,f="";if(e==="simple"){if(d.supportsTextContent){f=b.textContent}else{f=$(b).text()}}else{if(typeof e==="function"){f=e(b,a,c)}else if(typeof e==="object"&&e.hasOwnProperty(c)){f=e[c](b,a,c)}else{f=d.supportsTextContent?b.textContent:$(b).text()}}return $.trim(f)}function getParserById(a){var b,c=parsers.length;for(b=0;b<c;b++){if(parsers[b].id.toLowerCase()===a.toString().toLowerCase()){return parsers[b]}}return false}function detectParserForColumn(a,b,c,d){var e,f=parsers.length,g=false,h="",i=true;while(h===""&&i){c++;if(b[c]){g=b[c].cells[d];h=getElementText(a,g,d);if(a.config.debug){log("Checking if value was empty on row "+c+", column: "+d+": "+h)}}else{i=false}}for(e=1;e<f;e++){if(parsers[e].is(h,a,g)){return parsers[e]}}return parsers[0]}function buildParserCache(a,b){var c=a.config,d=$(a.tBodies).filter(":not(."+c.cssInfoBlock+")"),e=$.tablesorter,f,g,h,i,j,k,l,m,n,o="";if(d.length===0){return}f=d[0].rows;if(f[0]){g=[];h=f[0].cells.length;for(i=0;i<h;i++){j=b.filter(':not([colspan])[data-column="'+i+'"]:last,[colspan="1"][data-column="'+i+'"]:last');l=c.headers[i];n=getParserById(e.getData(j,l,"sorter"));c.empties[i]=e.getData(j,l,"empty")||c.emptyTo||(c.emptyToBottom?"bottom":"top");c.strings[i]=e.getData(j,l,"string")||c.stringTo||"max";if(!n){n=detectParserForColumn(a,f,-1,i)}if(c.debug){o+="column:"+i+"; parser:"+n.id+"; string:"+c.strings[i]+"; empty: "+c.empties[i]+"\n"}g.push(n)}}if(c.debug){log(o)}return g}function buildCache(a){var b=a.tBodies,c=a.config,d,e,f=c.parsers,g,h,i,j,k,l,m;c.cache={};if(c.debug){m=new Date}for(j=0;j<b.length;j++){c.cache[j]={row:[],normalized:[]};if(!$(b[j]).hasClass(c.cssInfoBlock)){$(b[j]).addClass("tablesorter-hidden");d=b[j]&&b[j].rows.length||0;e=b[j].rows[0]&&b[j].rows[0].cells.length||0;for(h=0;h<d;++h){k=$(b[j].rows[h]);l=[];if(k.hasClass(c.cssChildRow)){c.cache[j].row[c.cache[j].row.length-1]=c.cache[j].row[c.cache[j].row.length-1].add(k);continue}c.cache[j].row.push(k);for(i=0;i<e;++i){g=getElementText(a,k[0].cells[i],i);l.push(f[i].format(g,a,k[0].cells[i],i))}l.push(c.cache[j].normalized.length);c.cache[j].normalized.push(l)}$(b[j]).removeClass("tablesorter-hidden")}}if(c.debug){benchmark("Building cache for "+d+" rows",m)}}function getWidgetById(a){var b,c,d=widgets.length;for(b=0;b<d;b++){c=widgets[b];if(c&&c.hasOwnProperty("id")&&c.id.toLowerCase()===a.toLowerCase()){return c}}}function applyWidget(a,b){var c=a.config,d=c.widgets,e,f,g,h=d.length;if(c.debug){e=new Date}for(f=0;f<h;f++){g=getWidgetById(d[f]);if(g){if(b===true&&g.hasOwnProperty("init")){g.init(a,widgets,g)}else if(!b&&g.hasOwnProperty("format")){g.format(a)}}}if(c.debug){benchmark("Completed "+(b===true?"initializing":"applying")+" widgets",e)}}function appendToTable(a,b){var c=a.config,d=a.tBodies,e=[],f,g,h,i,j=c.cache,k,l,m,n,o,p,q;if(c.debug){q=new Date}for(n=0;n<d.length;n++){if(!$(d[n]).hasClass(c.cssInfoBlock)){$(d[n]).addClass("tablesorter-hidden");k=document.createDocumentFragment();f=j[n].row;g=j[n].normalized;h=g.length;i=h?g[0].length-1:0;for(l=0;l<h;l++){p=g[l][i];e.push(f[p]);if(!c.appender||!c.removeRows){o=f[p].length;for(m=0;m<o;m++){k.appendChild(f[p][m])}}}a.tBodies[n].appendChild(k);$(d[n]).removeClass("tablesorter-hidden")}}if(c.appender){c.appender(a,e)}if(c.debug){benchmark("Rebuilt table",q)}if(!b){applyWidget(a)}$(a).trigger("sortEnd",a)}function computeThIndexes(a){var b=[],c={},d=$(a).find("thead:eq(0) tr"),e,f,g,h,i,j,k,l,m,n,o,p;for(e=0;e<d.length;e++){j=d[e].cells;for(f=0;f<j.length;f++){i=j[f];k=i.parentNode.rowIndex;l=k+"-"+i.cellIndex;m=i.rowSpan||1;n=i.colSpan||1;if(typeof b[k]==="undefined"){b[k]=[]}for(g=0;g<b[k].length+1;g++){if(typeof b[k][g]==="undefined"){o=g;break}}c[l]=o;$(i).attr({"data-column":o});for(g=k;g<k+m;g++){if(typeof b[g]==="undefined"){b[g]=[]}p=b[g];for(h=o;h<o+n;h++){p[h]="x"}}}}return c}function formatSortingOrder(a){return/^d/i.test(a)||a===1}function buildHeaders(a){var b=computeThIndexes(a),c,d,e,f,g,h,i=a.config,j=$.tablesorter;i.headerList=[];if(i.debug){g=new Date}h=$(a).find(i.selectorHeaders).each(function(a){d=$(this);c=i.headers[a];this.innerHTML='<div class="tablesorter-header-inner">'+this.innerHTML+"</div>";if(i.onRenderHeader){i.onRenderHeader.apply(d,[a])}this.column=b[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=formatSortingOrder(j.getData(d,c,"sortInitialOrder")||i.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;if(j.getData(d,c,"sorter")==="false"){this.sortDisabled=true}this.lockedOrder=false;f=j.getData(d,c,"lockedOrder")||false;if(typeof f!=="undefined"&&f!==false){this.order=this.lockedOrder=formatSortingOrder(f)?[1,1,1]:[0,0,0]}if(!this.sortDisabled){e=d.addClass(i.cssHeader)}i.headerList[a]=this;d.parent().addClass(i.cssHeader)});if(a.config.debug){benchmark("Built headers:",g);log(h)}return h}function isValueInArray(a,b){var c,d=b.length;for(c=0;c<d;c++){if(b[c][0]===a){return true}}return false}function setHeadersCss(a,b,c){var d,e=[],f,g,h,i=[a.config.cssDesc,a.config.cssAsc];b.removeClass(i.join(" ")).each(function(){if(!this.sortDisabled){e[this.column]=$(this)}});h=c.length;for(f=0;f<h;f++){if(c[f][1]===2){continue}if(e[c[f][0]]){e[c[f][0]].addClass(i[c[f][1]])}d=b.filter('[data-column="'+c[f][0]+'"]');if(h>1&&d.length){for(g=0;g<d.length;g++){if(!d[g].sortDisabled){$(d[g]).addClass(i[c[f][1]])}}}}}function fixColumnWidth(a){if(a.config.widthFixed){var b=$("<colgroup>");$("tr:first td",a.tBodies[0]).each(function(){b.append($("<col>").css("width",$(this).width()))});$(a).prepend(b)}}function updateHeaderSortCount(a,b){var c,d,e,f=a.config,g=b.length;for(c=0;c<g;c++){d=b[c];e=f.headerList[d[0]];if(e){e.count=d[1]%(f.sortReset?3:2)}}}function getCachedSortType(a,b){return a&&a[b]?a[b].type||"":""}function multisort(table,sortList){var dynamicExp,sortWrapper,col,mx=0,dir=0,tc=table.config,l=sortList.length,bl=table.tBodies.length,sortTime,i,j,k,c,cache,lc,s,e,order,orgOrderCol;if(tc.debug){sortTime=new Date}for(k=0;k<bl;k++){dynamicExp="sortWrapper = function(a,b) {";cache=tc.cache[k];lc=cache.normalized.length;for(i=0;i<l;i++){c=sortList[i][0];order=sortList[i][1];s=/n/i.test(getCachedSortType(tc.parsers,c))?"Numeric":"Text";s+=order===0?"":"Desc";e="e"+i;if(/Numeric/.test(s)&&tc.strings[c]){for(j=0;j<lc;j++){col=Math.abs(parseFloat(cache.normalized[j][c]));mx=Math.max(mx,isNaN(col)?0:col)}if(typeof tc.string[tc.strings[c]]==="boolean"){dir=(order===0?1:-1)*(tc.string[tc.strings[c]]?-1:1)}else{dir=tc.strings[c]?tc.string[tc.strings[c]]||0:0}}dynamicExp+="var "+e+" = $.tablesorter.sort"+s+"(table,a["+c+"],b["+c+"],"+c+","+mx+","+dir+"); ";dynamicExp+="if ("+e+") { return "+e+"; } ";dynamicExp+="else { "}orgOrderCol=cache.normalized&&cache.normalized[0]?cache.normalized[0].length-1:0;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(i=0;i<l;i++){dynamicExp+="}; "}dynamicExp+="return 0; ";dynamicExp+="}; ";cache.normalized.sort(eval(dynamicExp))}if(tc.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time",sortTime)}}function checkResort(a,b,c){var d=a[0];if(b!==false){a.trigger("sorton",[d.config.sortList,function(){a.trigger("updateComplete");if(typeof c==="function"){c(d)}}])}else{a.trigger("updateComplete");if(typeof c==="function"){c(d)}}}this.version="2.3.11";var parsers=[],widgets=[];this.defaults={widthFixed:false,cancelSelection:true,dateFormat:"mmddyyyy",sortMultiSortKey:"shiftKey",usNumberFormat:true,delayInit:false,headers:{},ignoreCase:true,sortForce:null,sortList:[],sortAppend:null,sortInitialOrder:"asc",sortLocaleCompare:false,sortReset:false,sortRestart:false,emptyTo:"bottom",stringTo:"max",textExtraction:"simple",textSorter:null,widgets:[],widgetOptions:{zebra:["even","odd"]},initWidgets:true,initialized:null,onRenderHeader:null,tableClass:"tablesorter",cssAsc:"tablesorter-headerSortUp",cssChildRow:"expand-child",cssDesc:"tablesorter-headerSortDown",cssHeader:"tablesorter-header",cssInfoBlock:"tablesorter-infoOnly",selectorHeaders:"> thead th",selectorRemove:"tr.remove-me",debug:false,headerList:[],empties:{},strings:{},parsers:[]};this.benchmark=benchmark;this.hasInitialized=false;this.construct=function(a){return this.each(function(){if(!this.tHead||this.tBodies.length===0){return}var b,c,d,e,f,g,h,i,j,k,l,m=$.metadata;this.config={};e=$.extend(true,this.config,$.tablesorter.defaults,a);if(e.debug){$.data(this,"startoveralltimer",new Date)}d=$(this).addClass(e.tableClass);$.data(this,"tablesorter",e);e.supportsTextContent=$("<span>x</span>")[0].textContent==="x";e.string={max:1,min:-1,"max+":1,"max-":-1,zero:0,none:0,"null":0,top:true,bottom:false};b=buildHeaders(this);e.parsers=buildParserCache(this,b);if(!e.delayInit){buildCache(this)}fixColumnWidth(this);b.bind("mousedown.tablesorter mouseup.tablesorter",function(a,m){if(a.type==="mousedown"){l=(new Date).getTime();return!e.cancelSelection}if(m!==true&&(new Date).getTime()-l>500){return false}if(e.delayInit&&!e.cache){buildCache(d[0])}if(!this.sortDisabled){d.trigger("sortStart",d[0]);c=$(this);h=!a[e.sortMultiSortKey];this.count=(this.count+1)%(e.sortReset?3:2);if(e.sortRestart){f=this;b.each(function(){if(this!==f&&(h||!$(this).is("."+e.cssDesc+",."+e.cssAsc))){this.count=-1}})}f=this.column;if(h){e.sortList=[];if(e.sortForce!==null){i=e.sortForce;for(g=0;g<i.length;g++){if(i[g][0]!==f){e.sortList.push(i[g])}}}k=this.order[this.count];if(k<2){e.sortList.push([f,k]);if(this.colSpan>1){for(g=1;g<this.colSpan;g++){e.sortList.push([f+g,k])}}}}else{if(isValueInArray(f,e.sortList)){for(g=0;g<e.sortList.length;g++){j=e.sortList[g];k=e.headerList[j[0]];if(j[0]===f){j[1]=k.order[k.count];if(j[1]===2){e.sortList.splice(g,1);k.count=-1}}}}else{k=this.order[this.count];if(k<2){e.sortList.push([f,k]);if(this.colSpan>1){for(g=1;g<this.colSpan;g++){e.sortList.push([f+g,k])}}}}}if(e.sortAppend!==null){i=e.sortAppend;for(g=0;g<i.length;g++){if(i[g][0]!==f){e.sortList.push(i[g])}}}d.trigger("sortBegin",d[0]);setHeadersCss(d[0],b,e.sortList);multisort(d[0],e.sortList);appendToTable(d[0])}});if(e.cancelSelection){b.each(function(){this.onselectstart=function(){return false}})}d.bind("update",function(a,c,f){$(e.selectorRemove,this).remove();e.parsers=buildParserCache(this,b);buildCache(this);checkResort(d,c,f)}).bind("updateCell",function(a,b,c,f){var g=this,h=$(this).find("tbody"),i,j,k=h.index($(b).closest("tbody"));i=h.eq(k).find("tr").index($(b).closest("tr"));j=[i,b.cellIndex];g.config.cache[k].normalized[j[0]][j[1]]=e.parsers[j[1]].format(getElementText(g,b,j[1]),g,b,j[1]);checkResort(d,c,f)}).bind("addRows",function(a,b,c,f){var h,i=b.filter("tr").length,j=[],k=b[0].cells.length,l=this,m=$(this).find("tbody").index(b.closest("tbody"));for(h=0;h<i;h++){for(g=0;g<k;g++){j[g]=e.parsers[g].format(getElementText(l,b[h].cells[g],g),l,b[h].cells[g],g)}j.push(e.cache[m].row.length);e.cache[m].row.push([b[h]]);e.cache[m].normalized.push(j);j=[]}checkResort(d,c,f)}).bind("sorton",function(a,c,d,f){$(this).trigger("sortStart",this);var g=e.headerList.length;e.sortList=[];$.each(c,function(a,b){if(b[0]<g){e.sortList.push(c[a])}});updateHeaderSortCount(this,e.sortList);setHeadersCss(this,b,e.sortList);multisort(this,e.sortList);appendToTable(this,f);if(typeof d==="function"){d(this)}}).bind("appendCache",function(a,b){appendToTable(this,b)}).bind("applyWidgetId",function(a,b){getWidgetById(b).format(this)}).bind("applyWidgets",function(a,b){applyWidget(this,b)}).bind("destroy",function(a,b){$.tablesorter.destroy(this,b)});if(d.data()&&typeof d.data().sortlist!=="undefined"){e.sortList=d.data().sortlist}else if(m&&d.metadata()&&d.metadata().sortlist){e.sortList=d.metadata().sortlist}applyWidget(this,true);if(e.sortList.length>0){d.trigger("sorton",[e.sortList,{},!e.initWidgets])}else if(e.initWidgets){applyWidget(this)}this.hasInitialized=true;if(e.debug){$.tablesorter.benchmark("Overall initialization time",$.data(this,"startoveralltimer"))}d.trigger("tablesorter-initialized",this);if(typeof e.initialized==="function"){e.initialized(this)}})};this.sortText=function(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo],g=$.tablesorter.regex,h,i,j,k,l,m,n,o;if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:-f||-1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:f||1}if(typeof e.textSorter==="function"){return e.textSorter(b,c,a,d)}h=b.replace(g[0],"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");j=c.replace(g[0],"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");i=parseInt(b.match(g[2]),16)||h.length!==1&&b.match(g[1])&&Date.parse(b);k=parseInt(c.match(g[2]),16)||i&&c.match(g[1])&&Date.parse(c)||null;if(k){if(i<k){return-1}if(i>k){return 1}}o=Math.max(h.length,j.length);for(n=0;n<o;n++){l=!(h[n]||"").match(g[3])&&parseFloat(h[n])||h[n]||0;m=!(j[n]||"").match(g[3])&&parseFloat(j[n])||j[n]||0;if(isNaN(l)!==isNaN(m)){return isNaN(l)?1:-1}if(typeof l!==typeof m){l+="";m+=""}if(l<m){return-1}if(l>m){return 1}}return 0};this.sortTextDesc=function(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo];if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:f||1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:-f||-1}if(typeof e.textSorter==="function"){return e.textSorter(c,b,a,d)}return this.sortText(a,c,b)};this.getTextValue=function(a,b,c){if(b){var d,e=a.length,f=b+c;for(d=0;d<e;d++){f+=a.charCodeAt(d)}return c*f}return 0};this.sortNumeric=function(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:-h||-1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:h||1}if(isNaN(b)){b=this.getTextValue(b,e,f)}if(isNaN(c)){c=this.getTextValue(c,e,f)}return b-c};this.sortNumericDesc=function(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:h||1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:-h||-1}if(isNaN(b)){b=this.getTextValue(b,e,f)}if(isNaN(c)){c=this.getTextValue(c,e,f)}return c-b};this.destroy=function(a,b){var c=$(a),d=a.config;c.find("thead:first tr:not(."+d.cssHeader+")").remove();c.find("thead:first .tablesorter-resizer").remove();c.unbind("update updateCell addRows sorton appendCache applyWidgetId applyWidgets destroy mouseup mouseleave").find(d.selectorHeaders).unbind("click mousedown mousemove mouseup").removeClass(d.cssHeader+" "+d.cssAsc+" "+d.cssDesc);if(b!==false){c.removeClass(d.tableClass)}};this.addParser=function(a){var b,c=parsers.length,d=true;for(b=0;b<c;b++){if(parsers[b].id.toLowerCase()===a.id.toLowerCase()){d=false}}if(d){parsers.push(a)}};this.addWidget=function(a){widgets.push(a)};this.formatFloat=function(a,b){if(typeof a!=="string"||a===""){return a}if(b.config.usNumberFormat!==false){a=a.replace(/,/g,"")}else{a=a.replace(/[\s|\.]/g,"").replace(/,/g,".")}if(/^\s*\([.\d]+\)/.test(a)){a=a.replace(/^\s*\(/,"-").replace(/\)/,"")}var c=parseFloat(a);return isNaN(c)?$.trim(a):c};this.isDigit=function(a){return/^[\-+(]?\d+[)]?$/.test(a.replace(/[,.'\s]/g,""))};this.regex=[/(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,/^0x[0-9a-f]+$/i,/^0/];this.characterEquivalents={a:"\u00e1\u00e0\u00e2\u00e3\u00e4",A:"\u00c1\u00c0\u00c2\u00c3\u00c4",c:"\u00e7",C:"\u00c7",e:"\u00e9\u00e8\u00ea\u00eb",E:"\u00c9\u00c8\u00ca\u00cb",i:"\u00ed\u00ec\u0130\u00ee\u00ef",I:"\u00cd\u00cc\u0130\u00ce\u00cf",o:"\u00f3\u00f2\u00f4\u00f5\u00f6",O:"\u00d3\u00d2\u00d4\u00d5\u00d6",S:"\u00df",u:"\u00fa\u00f9\u00fb\u00fc",U:"\u00da\u00d9\u00db\u00dc"};this.replaceAccents=function(a){var b,c="[",d=this.characterEquivalents;if(!this.characterRegex){this.characterRegexArray={};for(b in d){if(typeof b==="string"){c+=d[b];this.characterRegexArray[b]=new RegExp("["+d[b]+"]","g")}}this.characterRegex=new RegExp(c+"]")}if(this.characterRegex.test(a)){for(b in d){if(typeof b==="string"){a=a.replace(this.characterRegexArray[b],b)}}}return a};this.getData=function(a,b,c){var d="",e=$(a),f,g;if(!e.length){return""}f=$.metadata?e.metadata():false;g=" "+(e.attr("class")||"");if(e.data()&&(typeof e.data(c)!=="undefined"||typeof e.data(c.toLowerCase())!=="undefined")){d+=e.data(c)||e.data(c.toLowerCase())}else if(f&&typeof f[c]!=="undefined"){d+=f[c]}else if(b&&typeof b[c]!=="undefined"){d+=b[c]}else if(g&&g.match(" "+c+"-")){d=g.match(new RegExp(" "+c+"-(\\w+)"))[1]||""}return $.trim(d)};this.clearTableBody=function(a){$(a.tBodies).filter(":not(."+a.config.cssInfoBlock+")").empty()}}})();var ts=$.tablesorter;$.fn.extend({tablesorter:ts.construct});ts.addParser({id:"text",is:function(a,b,c){return true},format:function(a,b,c,d){var e=b.config;a=$.trim(e.ignoreCase?a.toLocaleLowerCase():a);return e.sortLocaleCompare?ts.replaceAccents(a):a},type:"text"});ts.addParser({id:"currency",is:function(a){return/^\(?[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"ipAddress",is:function(a){return/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/.test(a)},format:function(a,b){var c,d=a.split("."),e="",f=d.length;for(c=0;c<f;c++){e+=("00"+d[c]).slice(-3)}return ts.formatFloat(e,b)},type:"numeric"});ts.addParser({id:"url",is:function(a){return/^(https?|ftp|file):\/\//.test(a)},format:function(a){return $.trim(a.replace(/(https?|ftp|file):\/\//,""))},type:"text"});ts.addParser({id:"isoDate",is:function(a){return/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},format:function(a,b){return ts.formatFloat(a!==""?(new Date(a.replace(/-/g,"/"))).getTime()||"":"",b)},type:"numeric"});ts.addParser({id:"percent",is:function(a){return/\d%\)?$/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/%/g,""),b)},type:"numeric"});ts.addParser({id:"usLongDate",is:function(a){return a.match(/^[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)))$/)},format:function(a,b){return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"shortDate",is:function(a){return/^(\d{2}|\d{4})[\/\-\,\.\s+]\d{2}[\/\-\.\,\s+](\d{2}|\d{4})$/.test(a)},format:function(a,b,c,d){var e=b.config,f=e.headerList[d],g=f.shortDateFormat;if(typeof g==="undefined"){g=f.shortDateFormat=ts.getData(f,e.headers[d],"dateFormat")||e.dateFormat}a=a.replace(/\s+/g," ").replace(/[\-|\.|\,]/g,"/");if(g==="mmddyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2")}else if(g==="ddmmyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1")}else if(g==="yyyymmdd"){a=a.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/,"$1/$2/$3")}return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"time",is:function(a){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(a)},format:function(a,b){return ts.formatFloat((new Date("2000/01/01 "+a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"digit",is:function(a){return ts.isDigit(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"metadata",is:function(a){return false},format:function(a,b,c){var d=b.config,e=!d.parserMetadataName?"sortValue":d.parserMetadataName;return $(c).metadata()[e]},type:"numeric"});ts.addWidget({id:"zebra",format:function(a){var b,c,d,e,f,g,h,i,j=a.config,k=new RegExp(j.cssChildRow,"i"),l=$(a).children("tbody:not(."+j.cssInfoBlock+")"),m=["even","odd"];m=j.widgetZebra&&j.hasOwnProperty("css")?j.widgetZebra.css:j.widgetOptions&&j.widgetOptions.hasOwnProperty("zebra")?j.widgetOptions.zebra:m;if(j.debug){g=new Date}for(h=0;h<l.length;h++){b=$(l[h]);i=b.children("tr").length;if(i>1){e=0;c=b.find("tr:visible");b.addClass("tablesorter-hidden");c.each(function(){d=$(this);if(!k.test(this.className)){e++}f=e%2===0;d.removeClass(m[f?1:0]).addClass(m[f?0:1])});b.removeClass("tablesorter-hidden")}}if(j.debug){ts.benchmark("Applying Zebra widget",g)}}})}(jQuery) diff --git a/sitestatic/jquery.tablesorter-2.3.11.js b/sitestatic/jquery.tablesorter-2.4.5.js index e52e66d..723cb91 100644 --- a/sitestatic/jquery.tablesorter-2.3.11.js +++ b/sitestatic/jquery.tablesorter-2.4.5.js @@ -1,5 +1,5 @@ /*! -* TableSorter 2.3.11 - Client-side table sorting with ease! +* TableSorter 2.4.5 - Client-side table sorting with ease! * @requires jQuery v1.2.6+ * * Copyright (c) 2007 Christian Bach @@ -14,24 +14,32 @@ * @author Christian Bach/christian.bach@polyester.se * @contributor Rob Garrison/https://github.com/Mottie/tablesorter */ +/*jshint evil:true, browser:true, jquery:true, unused:false */ +/*global console:false, alert:false */ !(function($) { + "use strict"; $.extend({ tablesorter: new function() { - this.version = "2.3.11"; + var ts = this; - var parsers = [], widgets = []; - this.defaults = { + ts.version = "2.4.5"; + + ts.parsers = []; + ts.widgets = []; + ts.defaults = { // appearance + theme : 'default', // adds tablesorter-{theme} to the table for styling widthFixed : false, // adds colgroup to fix widths of columns + showProcessing : false, // show an indeterminate timer icon in the header when the table is sorted or filtered. // functionality cancelSelection : true, // prevent text selection in the header - dateFormat : "mmddyyyy", // other options: "ddmmyyy" or "yyyymmdd" - sortMultiSortKey : "shiftKey", // key used to select additional columns + dateFormat : 'mmddyyyy', // other options: "ddmmyyy" or "yyyymmdd" + sortMultiSortKey : 'shiftKey', // key used to select additional columns usNumberFormat : true, // false for German "1.234.567,89" or French "1 234 567,89" - delayInit : false, // if false, the parsed table contents will not update until the first sort. + delayInit : false, // if false, the parsed table contents will not update until the first sort // sort options headers : {}, // set sorter, string, empty, locked order, sortInitialOrder, filter, etc. @@ -40,20 +48,20 @@ sortList : [], // Initial sort order; applied initially; updated when manually sorted sortAppend : null, // column(s) sorted last; always applied - sortInitialOrder : "asc", // sort direction on first click + sortInitialOrder : 'asc', // sort direction on first click sortLocaleCompare: false, // replace equivalent character (accented characters) sortReset : false, // third click on the header will reset column to default - unsorted sortRestart : false, // restart sort to "sortInitialOrder" when clicking on previously unsorted columns - emptyTo : "bottom", // sort empty cell to bottom, top, none, zero - stringTo : "max", // sort strings in numerical column as max, min, top, bottom, zero - textExtraction : "simple", // text extraction method/function - function(node, table, cellIndex){} + emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero + stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero + textExtraction : 'simple', // text extraction method/function - function(node, table, cellIndex){} textSorter : null, // use custom text sorter - function(a,b){ return a.sort(b); } // basic sort // widget options widgets: [], // method to add widgets, e.g. widgets: ['zebra'] widgetOptions : { - zebra : [ "even", "odd" ] // zebra widget alternating row class names + zebra : [ 'even', 'odd' ] // zebra widget alternating row class names }, initWidgets : true, // apply widgets on tablesorter initialization @@ -63,15 +71,19 @@ // css class names tableClass : 'tablesorter', - cssAsc : "tablesorter-headerSortUp", - cssChildRow : "expand-child", - cssDesc : "tablesorter-headerSortDown", - cssHeader : "tablesorter-header", - cssInfoBlock : "tablesorter-infoOnly", // don't sort tbody with this class name + cssAsc : 'tablesorter-headerSortUp', + cssChildRow : 'tablesorter-childRow', // previously "expand-child" + cssDesc : 'tablesorter-headerSortDown', + cssHeader : 'tablesorter-header', + cssHeaderRow : 'tablesorter-headerRow', + cssIcon : 'tablesorter-icon', // if this class exists, a <i> will be added to the header automatically + cssInfoBlock : 'tablesorter-infoOnly', // don't sort tbody with this class name + cssProcessing : 'tablesorter-processing', // processing icon applied to header during sort/filter // selectors - selectorHeaders : '> thead th', - selectorRemove : "tr.remove-me", + selectorHeaders : '> thead th, > thead td', + selectorSort : 'th, td', // jQuery selector of content within selectorHeaders that is clickable to trigger a sort + selectorRemove : '.remove-me', // advanced debug : false, @@ -100,8 +112,7 @@ log(s + " (" + (new Date().getTime() - d.getTime()) + "ms)"); } - this.benchmark = benchmark; - this.hasInitialized = false; + ts.benchmark = benchmark; function getElementText(table, node, cellIndex) { if (!node) { return ""; } @@ -125,19 +136,8 @@ return $.trim(text); } - /* parsers utils */ - function getParserById(name) { - var i, l = parsers.length; - for (i = 0; i < l; i++) { - if (parsers[i].id.toLowerCase() === (name.toString()).toLowerCase()) { - return parsers[i]; - } - } - return false; - } - function detectParserForColumn(table, rows, rowIndex, cellIndex) { - var i, l = parsers.length, + var i, l = ts.parsers.length, node = false, nodeValue = '', keepLooking = true; @@ -154,18 +154,18 @@ } } for (i = 1; i < l; i++) { - if (parsers[i].is(nodeValue, table, node)) { - return parsers[i]; + if (ts.parsers[i].is(nodeValue, table, node)) { + return ts.parsers[i]; } } // 0 is always the generic parser (text) - return parsers[0]; + return ts.parsers[0]; } function buildParserCache(table, $headers) { var c = table.config, tb = $(table.tBodies).filter(':not(.' + c.cssInfoBlock + ')'), - ts = $.tablesorter, rows, list, l, i, h, m, ch, cl, p, parsersDebug = ""; + rows, list, l, i, h, ch, p, parsersDebug = ""; if ( tb.length === 0) { return; } // In the case of empty tables rows = tb[0].rows; if (rows[0]) { @@ -176,8 +176,8 @@ h = $headers.filter(':not([colspan])[data-column="' + i + '"]:last,[colspan="1"][data-column="' + i + '"]:last'); ch = c.headers[i]; // get column parser - p = getParserById( ts.getData(h, ch, 'sorter') ); - // empty cells behaviour - keeping emptyToBottom for backwards compatibility. + p = ts.getParserById( ts.getData(h, ch, 'sorter') ); + // empty cells behaviour - keeping emptyToBottom for backwards compatibility c.empties[i] = ts.getData(h, ch, 'empty') || c.emptyTo || (c.emptyToBottom ? 'bottom' : 'top' ); // text strings behaviour in numerical sorts c.strings[i] = ts.getData(h, ch, 'string') || c.stringTo || 'max'; @@ -208,11 +208,14 @@ if (tc.debug) { cacheTime = new Date(); } + // processing icon + if (tc.showProcessing) { + ts.isProcessing(table, true); + } for (k = 0; k < b.length; k++) { tc.cache[k] = { row: [], normalized: [] }; // ignore tbodies with class name from css.cssInfoBlock if (!$(b[k]).hasClass(tc.cssInfoBlock)) { - $(b[k]).addClass('tablesorter-hidden'); totalRows = (b[k] && b[k].rows.length) || 0; totalCells = (b[k].rows[0] && b[k].rows[0].cells.length) || 0; for (i = 0; i < totalRows; ++i) { @@ -235,42 +238,13 @@ cols.push(tc.cache[k].normalized.length); // add position for rowCache tc.cache[k].normalized.push(cols); } - $(b[k]).removeClass('tablesorter-hidden'); } } - if (tc.debug) { - benchmark("Building cache for " + totalRows + " rows", cacheTime); - } - } - - function getWidgetById(name) { - var i, w, l = widgets.length; - for (i = 0; i < l; i++) { - w = widgets[i]; - if (w && w.hasOwnProperty('id') && w.id.toLowerCase() === name.toLowerCase()) { - return w; - } - } - } - - function applyWidget(table, init) { - var tc = table.config, c = tc.widgets, - time, i, w, l = c.length; - if (tc.debug) { - time = new Date(); - } - for (i = 0; i < l; i++) { - w = getWidgetById(c[i]); - if ( w ) { - if (init === true && w.hasOwnProperty('init')) { - w.init(table, widgets, w); - } else if (!init && w.hasOwnProperty('format')) { - w.format(table); - } - } + if (tc.showProcessing) { + ts.isProcessing(table); // remove processing icon } if (tc.debug) { - benchmark("Completed " + (init === true ? "initializing" : "applying") + " widgets", time); + benchmark("Building cache for " + totalRows + " rows", cacheTime); } } @@ -279,15 +253,17 @@ var c = table.config, b = table.tBodies, rows = [], - r, n, totalRows, checkCell, c2 = c.cache, - f, i, j, k, l, pos, appendTime; + c2 = c.cache, + r, n, totalRows, checkCell, $bk, $tb, + i, j, k, l, pos, appendTime; if (c.debug) { appendTime = new Date(); } for (k = 0; k < b.length; k++) { - if (!$(b[k]).hasClass(c.cssInfoBlock)){ - $(b[k]).addClass('tablesorter-hidden'); - f = document.createDocumentFragment(); + $bk = $(b[k]); + if (!$bk.hasClass(c.cssInfoBlock)) { + // get tbody + $tb = ts.processTbody(table, $bk, true); r = c2[k].row; n = c2[k].normalized; totalRows = n.length; @@ -299,12 +275,12 @@ if (!c.appender || !c.removeRows) { l = r[pos].length; for (j = 0; j < l; j++) { - f.appendChild(r[pos][j]); + $tb.append(r[pos][j]); } } } - table.tBodies[k].appendChild(f); - $(b[k]).removeClass('tablesorter-hidden'); + // restore tbody + ts.processTbody(table, $tb, false); } } if (c.appender) { @@ -314,7 +290,7 @@ benchmark("Rebuilt table", appendTime); } // apply table widgets - if (!init) { applyWidget(table); } + if (!init) { ts.applyWidget(table); } // trigger sortend $(table).trigger("sortEnd", table); } @@ -325,7 +301,7 @@ function computeThIndexes(t) { var matrix = [], lookup = {}, - trs = $(t).find('thead:eq(0) tr'), + trs = $(t).find('thead:eq(0) tr, tfoot tr'), i, j, k, l, c, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol, matrixrow; for (i = 0; i < trs.length; i++) { cells = trs[i].cells; @@ -367,36 +343,38 @@ return (/^d/i.test(v) || v === 1); } - function buildHeaders(table) { var header_index = computeThIndexes(table), ch, $t, - $th, lock, time, $tableHeaders, c = table.config, ts = $.tablesorter; + t, lock, time, $tableHeaders, c = table.config; c.headerList = []; if (c.debug) { time = new Date(); } - $tableHeaders = $(table).find(c.selectorHeaders) - .each(function(index) { + $tableHeaders = $(table).find(c.selectorHeaders).each(function(index) { $t = $(this); ch = c.headers[index]; - this.innerHTML = '<div class="tablesorter-header-inner">' + this.innerHTML + '</div>'; // faster than wrapInner + t = c.cssIcon ? '<i class="' + c.cssIcon + '"></i>' : ''; // add icon if cssIcon option exists + this.innerHTML = '<div class="tablesorter-header-inner">' + this.innerHTML + t + '</div>'; // faster than wrapInner if (c.onRenderHeader) { c.onRenderHeader.apply($t, [index]); } this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex]; this.order = formatSortingOrder( ts.getData($t, ch, 'sortInitialOrder') || c.sortInitialOrder ) ? [1,0,2] : [0,1,2]; this.count = -1; // set to -1 because clicking on the header automatically adds one - if (ts.getData($t, ch, 'sorter') === 'false') { this.sortDisabled = true; } + if (ts.getData($t, ch, 'sorter') === 'false') { + this.sortDisabled = true; + $t.addClass('sorter-false'); + } else { + $t.removeClass('sorter-false'); + } this.lockedOrder = false; lock = ts.getData($t, ch, 'lockedOrder') || false; if (typeof(lock) !== 'undefined' && lock !== false) { this.order = this.lockedOrder = formatSortingOrder(lock) ? [1,1,1] : [0,0,0]; } - if (!this.sortDisabled) { - $th = $t.addClass(c.cssHeader); - } + $t.addClass( this.sortDisabled ? 'sorter-false' : c.cssHeader ); // add cell to headerList c.headerList[index] = this; // add to parent in case there are multiple rows - $t.parent().addClass(c.cssHeader); + $t.parent().addClass(c.cssHeaderRow); }); if (table.config.debug) { benchmark("Built headers:", time); @@ -405,39 +383,30 @@ return $tableHeaders; } - function isValueInArray(v, a) { - var i, l = a.length; - for (i = 0; i < l; i++) { - if (a[i][0] === v) { - return true; - } - } - return false; - } - - function setHeadersCss(table, $headers, list) { - var f, h = [], i, j, l, css = [table.config.cssDesc, table.config.cssAsc]; + function setHeadersCss(table, $headers) { + var f, i, j, l, + c = table.config, + list = c.sortList, + css = [c.cssDesc, c.cssAsc], + // find the footer + $t = $(table).find('tfoot tr').children().removeClass(css.join(' ')); // remove all header information - $headers - .removeClass(css.join(' ')) - .each(function() { - if (!this.sortDisabled) { - h[this.column] = $(this); - } - }); + $headers.removeClass(css.join(' ')); l = list.length; for (i = 0; i < l; i++) { - if (list[i][1] === 2) { continue; } // direction = 2 means reset! - if (h[list[i][0]]) { - // add class if cell exists - fix for issue #78 - h[list[i][0]].addClass(css[list[i][1]]); - } - // multicolumn sorting updating - f = $headers.filter('[data-column="' + list[i][0] + '"]'); - if (l > 1 && f.length) { - for (j = 0; j < f.length; j++) { - if (!f[j].sortDisabled) { - $(f[j]).addClass(css[list[i][1]]); + // direction = 2 means reset! + if (list[i][1] !== 2) { + // multicolumn sorting updating - choose the :last in case there are nested columns + f = $headers.not('.sorter-false').filter('[data-column="' + list[i][0] + '"]' + (l === 1 ? ':last' : '') ); + if (f.length) { + for (j = 0; j < f.length; j++) { + if (!f[j].sortDisabled) { + f.eq(j).addClass(css[list[i][1]]); + // add sorted class to footer, if it exists + if ($t.length) { + $t.filter('[data-column="' + list[i][0] + '"]').eq(j).addClass(css[list[i][1]]); + } + } } } } @@ -445,35 +414,41 @@ } function fixColumnWidth(table) { - if (table.config.widthFixed) { - var colgroup = $('<colgroup>'); + if (table.config.widthFixed && $(table).find('colgroup').length === 0) { + var colgroup = $('<colgroup>'), + overallWidth = $(table).width(); $("tr:first td", table.tBodies[0]).each(function() { - colgroup.append($('<col>').css('width', $(this).width())); + colgroup.append($('<col>').css('width', parseInt(($(this).width()/overallWidth)*1000, 10)/10 + '%')); }); $(table).prepend(colgroup); } } - function updateHeaderSortCount(table, sortList) { - var i, s, o, c = table.config, - l = sortList.length; - for (i = 0; i < l; i++) { - s = sortList[i]; + function updateHeaderSortCount(table, list) { + var s, o, c = table.config, + l = c.headerList.length, + sl = list || c.sortList; + c.sortList = []; + $.each(sl, function(i,v){ + // ensure all sortList values are numeric - fixes #127 + s = [ parseInt(v[0], 10), parseInt(v[1], 10) ]; + // make sure header exists o = c.headerList[s[0]]; if (o) { // prevents error if sorton array is wrong + c.sortList.push(s); o.count = s[1] % (c.sortReset ? 3 : 2); } - } + }); } function getCachedSortType(parsers, i) { return (parsers && parsers[i]) ? parsers[i].type || '' : ''; } - /* sorting methods - reverted sorting method back to version 2.0.3 */ - function multisort(table, sortList) { + // sort multiple columns + function multisort(table) { var dynamicExp, sortWrapper, col, mx = 0, dir = 0, tc = table.config, - l = sortList.length, bl = table.tBodies.length, + sortList = tc.sortList, l = sortList.length, bl = table.tBodies.length, sortTime, i, j, k, c, cache, lc, s, e, order, orgOrderCol; if (tc.debug) { sortTime = new Date(); } for (k = 0; k < bl; k++) { @@ -514,48 +489,55 @@ dynamicExp += "}; "; cache.normalized.sort(eval(dynamicExp)); // sort using eval expression } - if (tc.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order+ " time", sortTime); } + if (tc.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time", sortTime); } } - function checkResort($table, flag, callback) { + function resortComplete($table, callback){ var t = $table[0]; + $table.trigger('updateComplete'); + if (typeof callback === "function") { + callback(t); + } + } + + function checkResort($table, flag, callback) { if (flag !== false) { - $table.trigger("sorton", [t.config.sortList, function(){ - $table.trigger('updateComplete'); - if (typeof callback === "function") { - callback(t); - } + $table.trigger("sorton", [$table[0].config.sortList, function(){ + resortComplete($table, callback); }]); } else { - $table.trigger('updateComplete'); - if (typeof callback === "function") { - callback(t); - } + resortComplete($table, callback); } } /* public methods */ - this.construct = function(settings) { + ts.construct = function(settings) { return this.each(function() { - // if no thead or tbody quit. - if (!this.tHead || this.tBodies.length === 0) { return; } + // if no thead or tbody, or tablesorter is already present, quit + if (!this.tHead || this.tBodies.length === 0 || this.hasInitialized === true) { return; } // declare - var $headers, $cell, $this, - c, i, j, k, a, s, o, downTime, + var $headers, $cell, $this = $(this), + c, i, j, k = '', a, s, o, downTime, m = $.metadata; + // initialization flag + this.hasInitialized = false; // new blank config object this.config = {}; - // merge and extend. - c = $.extend(true, this.config, $.tablesorter.defaults, settings); - - if (c.debug) { $.data( this, 'startoveralltimer', new Date()); } - // store common expression for speed - $this = $(this).addClass(c.tableClass); + // merge and extend + c = $.extend(true, this.config, ts.defaults, settings); // save the settings where they read $.data(this, "tablesorter", c); + if (c.debug) { $.data( this, 'startoveralltimer', new Date()); } + // constants c.supportsTextContent = $('<span>x</span>')[0].textContent === 'x'; + c.supportsDataObject = parseFloat($.fn.jquery) >= 1.4; // digit sort text location; keeping max+/- for backwards compatibility c.string = { 'max': 1, 'min': -1, 'max+': 1, 'max-': -1, 'zero': 0, 'none': 0, 'null': 0, 'top': true, 'bottom': false }; + // add table theme class only if there isn't already one there + if (!/tablesorter\-/.test($this.attr('class'))) { + k = (c.theme !== '' ? ' tablesorter-' + c.theme : ''); + } + $this.addClass(c.tableClass + k); // build headers $headers = buildHeaders(this); // try to auto detect column type, and store in tables config @@ -563,29 +545,36 @@ // build the cache for the tbody cells // delayInit will delay building the cache until the user starts a sort if (!c.delayInit) { buildCache(this); } - // 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.bind('mousedown.tablesorter mouseup.tablesorter', function(e, external) { + $headers + // http://stackoverflow.com/questions/5312849/jquery-find-self + .find('*').andSelf().filter(c.selectorSort) + .unbind('mousedown.tablesorter mouseup.tablesorter') + .bind('mousedown.tablesorter mouseup.tablesorter', function(e, external) { + // jQuery v1.2.6 doesn't have closest() + var $cell = this.tagName.match('TH|TD') ? $(this) : $(this).parents('th, td').filter(':last'), cell = $cell[0]; + // only recognize left clicks + if ((e.which || e.button) !== 1) { return false; } + // set timer on mousedown if (e.type === 'mousedown') { downTime = new Date().getTime(); - return !c.cancelSelection; + return e.target.tagName === "INPUT" ? '' : !c.cancelSelection; } - // prevent resizable widget from initializing a sort (long clicks are ignored) - if (external !== true && (new Date().getTime() - downTime > 500)) { return false; } + // ignore long clicks (prevents resizable widget from initializing a sort) + if (external !== true && (new Date().getTime() - downTime > 250)) { return false; } if (c.delayInit && !c.cache) { buildCache($this[0]); } - if (!this.sortDisabled) { - // Only call sortStart if sorting is enabled. + if (!cell.sortDisabled) { + // Only call sortStart if sorting is enabled $this.trigger("sortStart", $this[0]); // store exp, for speed - $cell = $(this); + // $cell = $(this); k = !e[c.sortMultiSortKey]; // get current column sort order - this.count = (this.count + 1) % (c.sortReset ? 3 : 2); + cell.count = (cell.count + 1) % (c.sortReset ? 3 : 2); // reset all sorts on non-current column - issue #30 if (c.sortRestart) { - i = this; + i = cell; $headers.each(function() { // only reset counts on columns that weren't just clicked on and if not included in a multisort if (this !== i && (k || !$(this).is('.' + c.cssDesc + ',.' + c.cssAsc))) { @@ -594,7 +583,7 @@ }); } // get current column index - i = this.column; + i = cell.column; // user only wants to sort on one column if (k) { // flush the sort list @@ -608,21 +597,27 @@ } } // add column to sort list - o = this.order[this.count]; + o = cell.order[cell.count]; if (o < 2) { c.sortList.push([i, o]); // add other columns if header spans across multiple - if (this.colSpan > 1) { - for (j = 1; j < this.colSpan; j++) { + if (cell.colSpan > 1) { + for (j = 1; j < cell.colSpan; j++) { c.sortList.push([i + j, o]); } } } // multi column sorting } else { - // the user has clicked on an already sorted column. - if (isValueInArray(i, c.sortList)) { - // reverse the sorting direction for all tables. + // get rid of the sortAppend before adding more - fixes issue #115 + if (c.sortAppend && c.sortList.length > 1) { + if (ts.isValueInArray(c.sortAppend[0][0], c.sortList)) { + c.sortList.pop(); + } + } + // the user has clicked on an already sorted column + if (ts.isValueInArray(i, c.sortList)) { + // reverse the sorting direction for all tables for (j = 0; j < c.sortList.length; j++) { s = c.sortList[j]; o = c.headerList[s[0]]; @@ -636,12 +631,12 @@ } } else { // add column to sort list array - o = this.order[this.count]; + o = cell.order[cell.count]; if (o < 2) { c.sortList.push([i, o]); // add other columns if header spans across multiple - if (this.colSpan > 1) { - for (j = 1; j < this.colSpan; j++) { + if (cell.colSpan > 1) { + for (j = 1; j < cell.colSpan; j++) { c.sortList.push([i + j, o]); } } @@ -658,10 +653,13 @@ } // sortBegin event triggered immediately before the sort $this.trigger("sortBegin", $this[0]); - // set css for headers - setHeadersCss($this[0], $headers, c.sortList); - multisort($this[0], c.sortList); - appendToTable($this[0]); + // setTimeout needed so the processing icon shows up + setTimeout(function(){ + // set css for headers + setHeadersCss($this[0], $headers); + multisort($this[0]); + appendToTable($this[0]); + }, 1); } }); if (c.cancelSelection) { @@ -674,24 +672,33 @@ } // apply easy methods that trigger binded events $this + .unbind('update updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave') .bind("update", function(e, resort, callback) { // remove rows/elements before update $(c.selectorRemove, this).remove(); - // rebuild parsers. + // rebuild parsers c.parsers = buildParserCache(this, $headers); // rebuild the cache map buildCache(this); checkResort($this, resort, callback); }) .bind("updateCell", function(e, cell, resort, callback) { - // get position from the dom. - var t = this, $tb = $(this).find('tbody'), row, pos, + // get position from the dom + var l, row, icell, + t = this, $tb = $(this).find('tbody'), // update cache - format: function(s, table, cell, cellIndex) - tbdy = $tb.index( $(cell).closest('tbody') ); - row = $tb.eq(tbdy).find('tr').index( $(cell).closest('tr') ); - pos = [ row, cell.cellIndex]; - t.config.cache[tbdy].normalized[pos[0]][pos[1]] = c.parsers[pos[1]].format( getElementText(t, cell, pos[1]), t, cell, pos[1] ); - checkResort($this, resort, callback); + // no closest in jQuery v1.2.6 - tbdy = $tb.index( $(cell).closest('tbody') ),$row = $(cell).closest('tr'); + tbdy = $tb.index( $(cell).parents('tbody').filter(':last') ), + $row = $(cell).parents('tr').filter(':last'); + // tbody may not exist if update is initialized while tbody is removed for processing + if ($tb.length && tbdy >= 0) { + row = $tb.eq(tbdy).find('tr').index( $row ); + icell = cell.cellIndex; + l = t.config.cache[tbdy].normalized[row].length - 1; + t.config.cache[tbdy].row[t.config.cache[tbdy].normalized[row][l]] = $row; + t.config.cache[tbdy].normalized[row][icell] = c.parsers[icell].format( getElementText(t, cell, icell), t, cell, icell ); + checkResort($this, resort, callback); + } }) .bind("addRows", function(e, $row, resort, callback) { var i, rows = $row.filter('tr').length, @@ -715,68 +722,158 @@ }) .bind("sorton", function(e, list, callback, init) { $(this).trigger("sortStart", this); - var l = c.headerList.length; - c.sortList = []; - $.each(list, function(i,v){ - // make sure column exists - if (v[0] < l) { c.sortList.push(list[i]); } - }); // update header count index - updateHeaderSortCount(this, c.sortList); + updateHeaderSortCount(this, list); // set css for headers - setHeadersCss(this, $headers, c.sortList); + setHeadersCss(this, $headers); // sort the table and append it to the dom - multisort(this, c.sortList); + multisort(this); appendToTable(this, init); if (typeof callback === "function") { callback(this); } }) - .bind("appendCache", function(e, init) { + .bind("appendCache", function(e, callback, init) { appendToTable(this, init); + if (typeof callback === "function") { + callback(this); + } }) .bind("applyWidgetId", function(e, id) { - getWidgetById(id).format(this); + ts.getWidgetById(id).format(this, c, c.widgetOptions); }) .bind("applyWidgets", function(e, init) { // apply widgets - applyWidget(this, init); + ts.applyWidget(this, init); + }) + .bind("refreshWidgets", function(e, all, dontapply){ + ts.refreshWidgets(this, all, dontapply); }) - .bind("destroy", function(e,c){ - $.tablesorter.destroy(this, c); + .bind("destroy", function(e, c, cb){ + ts.destroy(this, c, cb); }); // get sort list from jQuery data or metadata - if ($this.data() && typeof $this.data().sortlist !== 'undefined') { + // in jQuery < 1.4, an error occurs when calling $this.data() + if (c.supportsDataObject && typeof $this.data().sortlist !== 'undefined') { c.sortList = $this.data().sortlist; } else if (m && ($this.metadata() && $this.metadata().sortlist)) { c.sortList = $this.metadata().sortlist; } // apply widget init code - applyWidget(this, true); - // if user has supplied a sort list to constructor. + ts.applyWidget(this, true); + // if user has supplied a sort list to constructor if (c.sortList.length > 0) { $this.trigger("sorton", [c.sortList, {}, !c.initWidgets]); } else if (c.initWidgets) { // apply widget format - applyWidget(this); + ts.applyWidget(this); + } + + // fixate columns if the users supplies the fixedWidth option + // do this after theme has been applied + fixColumnWidth(this); + + // show processesing icon + if (c.showProcessing) { + $this + .unbind('sortBegin sortEnd') + .bind('sortBegin sortEnd', function(e) { + ts.isProcessing($this[0], e.type === 'sortBegin'); + }); } // initialized this.hasInitialized = true; if (c.debug) { - $.tablesorter.benchmark("Overall initialization time", $.data( this, 'startoveralltimer')); + ts.benchmark("Overall initialization time", $.data( this, 'startoveralltimer')); } $this.trigger('tablesorter-initialized', this); if (typeof c.initialized === 'function') { c.initialized(this); } }); }; + // *** Process table *** + // add processing indicator + ts.isProcessing = function(table, toggle, $ths) { + var c = table.config, + // default to all headers + $h = $ths || $(table).find('.' + c.cssHeader); + if (toggle) { + if (c.sortList.length > 0) { + // get headers from the sortList + $h = $h.filter(function(){ + // get data-column from attr to keep compatibility with jQuery 1.2.6 + return this.sortDisabled ? false : ts.isValueInArray( parseFloat($(this).attr('data-column')), c.sortList); + }); + } + $h.addClass(c.cssProcessing); + } else { + $h.removeClass(c.cssProcessing); + } + }; + + // detach tbody but save the position + // don't use tbody because there are portions that look for a tbody index (updateCell) + ts.processTbody = function(table, $tb, getIt){ + var t, holdr; + if (getIt) { + $tb.before('<span class="tablesorter-savemyplace"/>'); + holdr = ($.fn.detach) ? $tb.detach() : $tb.remove(); + return holdr; + } + holdr = $(table).find('span.tablesorter-savemyplace'); + $tb.insertAfter( holdr ); + holdr.remove(); + }; + + ts.clearTableBody = function(table) { + $(table.tBodies).filter(':not(.' + table.config.cssInfoBlock + ')').empty(); + }; + + ts.destroy = function(table, removeClasses, callback){ + var $t = $(table), c = table.config, + $h = $t.find('thead:first'); + // clear flag in case the plugin is initialized again + table.hasInitialized = false; + // remove widget added rows + $h.find('tr:not(.' + c.cssHeaderRow + ')').remove(); + // remove resizer widget stuff + $h.find('.tablesorter-resizer').remove(); + // remove all widgets + ts.refreshWidgets(table, true, true); + // disable tablesorter + $t + .removeData('tablesorter') + .unbind('update updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave') + .find('.' + c.cssHeader) + .unbind('click mousedown mousemove mouseup') + .removeClass(c.cssHeader + ' ' + c.cssAsc + ' ' + c.cssDesc) + .find('.tablesorter-header-inner').each(function(){ + if (c.cssIcon !== '') { $(this).find('.' + c.cssIcon).remove(); } + $(this).replaceWith( $(this).contents() ); + }); + if (removeClasses !== false) { + $t.removeClass(c.tableClass); + } + if (typeof callback === 'function') { + callback(table); + } + }; + + // *** sort functions *** + // regex used in natural sort + ts.regex = [ + /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, // chunk/tokenize numbers & letters + /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, //date + /^0x[0-9a-f]+$/i // hex + ]; + // Natural sort - https://github.com/overset/javascript-natural-sort - this.sortText = function(table, a, b, col) { + ts.sortText = function(table, a, b, col) { if (a === b) { return 0; } var c = table.config, e = c.string[ (c.empties[col] || c.emptyTo ) ], - r = $.tablesorter.regex, xN, xD, yN, yD, xF, yF, i, mx; + r = ts.regex, xN, xD, yN, yD, xF, yF, i, mx; if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : -e || -1; } if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : e || 1; } if (typeof c.textSorter === 'function') { return c.textSorter(a, b, table, col); } @@ -794,9 +891,9 @@ mx = Math.max(xN.length, yN.length); // natural sorting through split numeric strings and default strings for (i = 0; i < mx; i++) { - // find floats not starting with '0', string or 0 if not defined (Clint Priest) - xF = (!(xN[i] || '').match(r[3]) && parseFloat(xN[i])) || xN[i] || 0; - yF = (!(yN[i] || '').match(r[3]) && parseFloat(yN[i])) || yN[i] || 0; + // find floats not starting with '0', string or 0 if not defined + xF = isNaN(xN[i]) ? xN[i] || 0 : parseFloat(xN[i]) || 0; + yF = isNaN(yN[i]) ? yN[i] || 0 : parseFloat(yN[i]) || 0; // handle numeric vs string comparison - number < string - (Kyle Adams) if (isNaN(xF) !== isNaN(yF)) { return (isNaN(xF)) ? 1 : -1; } // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' @@ -810,19 +907,19 @@ return 0; }; - this.sortTextDesc = function(table, a, b, col) { + ts.sortTextDesc = function(table, a, b, col) { if (a === b) { return 0; } var c = table.config, e = c.string[ (c.empties[col] || c.emptyTo ) ]; if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : e || 1; } if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : -e || -1; } if (typeof c.textSorter === 'function') { return c.textSorter(b, a, table, col); } - return this.sortText(table, b, a); + return ts.sortText(table, b, a); }; // return text string value by adding up ascii value // so the text is somewhat sorted when using a digital sort // this is NOT an alphanumeric sort - this.getTextValue = function(a, mx, d) { + ts.getTextValue = function(a, mx, d) { if (mx) { // make sure the text value is greater than the max numerical value (mx) var i, l = a.length, n = mx + d; @@ -834,89 +931,28 @@ return 0; }; - this.sortNumeric = function(table, a, b, col, mx, d) { + ts.sortNumeric = function(table, a, b, col, mx, d) { if (a === b) { return 0; } var c = table.config, e = c.string[ (c.empties[col] || c.emptyTo ) ]; if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : -e || -1; } if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : e || 1; } - if (isNaN(a)) { a = this.getTextValue(a, mx, d); } - if (isNaN(b)) { b = this.getTextValue(b, mx, d); } + if (isNaN(a)) { a = ts.getTextValue(a, mx, d); } + if (isNaN(b)) { b = ts.getTextValue(b, mx, d); } return a - b; }; - this.sortNumericDesc = function(table, a, b, col, mx, d) { + ts.sortNumericDesc = function(table, a, b, col, mx, d) { if (a === b) { return 0; } var c = table.config, e = c.string[ (c.empties[col] || c.emptyTo ) ]; if (a === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? -1 : 1) : e || 1; } if (b === '' && e !== 0) { return (typeof(e) === 'boolean') ? (e ? 1 : -1) : -e || -1; } - if (isNaN(a)) { a = this.getTextValue(a, mx, d); } - if (isNaN(b)) { b = this.getTextValue(b, mx, d); } + if (isNaN(a)) { a = ts.getTextValue(a, mx, d); } + if (isNaN(b)) { b = ts.getTextValue(b, mx, d); } return b - a; }; - this.destroy = function(table, removeClasses){ - var $t = $(table), c = table.config; - // remove widget added rows - $t.find('thead:first tr:not(.' + c.cssHeader + ')').remove(); - // remove resizer widget stuff - $t.find('thead:first .tablesorter-resizer').remove(); - // disable tablesorter - $t - .unbind('update updateCell addRows sorton appendCache applyWidgetId applyWidgets destroy mouseup mouseleave') - .find(c.selectorHeaders) - .unbind('click mousedown mousemove mouseup') - .removeClass(c.cssHeader + ' ' + c.cssAsc + ' ' + c.cssDesc); - if (removeClasses !== false) { - $t.removeClass(c.tableClass); - } - }; - - this.addParser = function(parser) { - var i, l = parsers.length, a = true; - for (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, table) { - if (typeof(s) !== 'string' || s === '') { return s; } - if (table.config.usNumberFormat !== false) { - // US Format - 1,234,567.89 -> 1234567.89 - 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,'.'); - } - if(/^\s*\([.\d]+\)/.test(s)) { - s = s.replace(/^\s*\(/,'-').replace(/\)/,''); - } - var i = parseFloat(s); - // return the text instead of zero - return isNaN(i) ? $.trim(s) : i; - }; - this.isDigit = function(s) { - // replace all unwanted chars and match. - return (/^[\-+(]?\d+[)]?$/).test(s.replace(/[,.'\s]/g, '')); - }; - - // regex used in natural sort - this.regex = [ - /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi, // chunk/tokenize numbers & letters - /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, //date - /^0x[0-9a-f]+$/i, // hex - /^0/ // leading zeros - ]; // used when replacing accented characters during sorting - this.characterEquivalents = { + ts.characterEquivalents = { "a" : "\u00e1\u00e0\u00e2\u00e3\u00e4", // áàâãä "A" : "\u00c1\u00c0\u00c2\u00c3\u00c4", // ÁÀÂÃÄ "c" : "\u00e7", // ç @@ -931,37 +967,130 @@ "u" : "\u00fa\u00f9\u00fb\u00fc", // úùûü "U" : "\u00da\u00d9\u00db\u00dc" // ÚÙÛÜ }; - this.replaceAccents = function(s) { - var a, acc = '[', eq = this.characterEquivalents; - if (!this.characterRegex) { - this.characterRegexArray = {}; + ts.replaceAccents = function(s) { + var a, acc = '[', eq = ts.characterEquivalents; + if (!ts.characterRegex) { + ts.characterRegexArray = {}; for (a in eq) { if (typeof a === 'string') { acc += eq[a]; - this.characterRegexArray[a] = new RegExp('[' + eq[a] + ']', 'g'); + ts.characterRegexArray[a] = new RegExp('[' + eq[a] + ']', 'g'); } } - this.characterRegex = new RegExp(acc + ']'); + ts.characterRegex = new RegExp(acc + ']'); } - if (this.characterRegex.test(s)) { + if (ts.characterRegex.test(s)) { for (a in eq) { if (typeof a === 'string') { - s = s.replace( this.characterRegexArray[a], a ); + s = s.replace( ts.characterRegexArray[a], a ); } } } return s; }; + // *** utilities *** + ts.isValueInArray = function(v, a) { + var i, l = a.length; + for (i = 0; i < l; i++) { + if (a[i][0] === v) { + return true; + } + } + return false; + }; + + ts.addParser = function(parser) { + var i, l = ts.parsers.length, a = true; + for (i = 0; i < l; i++) { + if (ts.parsers[i].id.toLowerCase() === parser.id.toLowerCase()) { + a = false; + } + } + if (a) { + ts.parsers.push(parser); + } + }; + + ts.getParserById = function(name) { + var i, l = ts.parsers.length; + for (i = 0; i < l; i++) { + if (ts.parsers[i].id.toLowerCase() === (name.toString()).toLowerCase()) { + return ts.parsers[i]; + } + } + return false; + }; + + ts.addWidget = function(widget) { + ts.widgets.push(widget); + }; + + ts.getWidgetById = function(name) { + var i, w, l = ts.widgets.length; + for (i = 0; i < l; i++) { + w = ts.widgets[i]; + if (w && w.hasOwnProperty('id') && w.id.toLowerCase() === name.toLowerCase()) { + return w; + } + } + }; + + ts.applyWidget = function(table, init) { + var c = table.config, + wo = c.widgetOptions, + ws = c.widgets.sort().reverse(), // ensure that widgets are always applied in a certain order + time, i, w, l = ws.length; + // make zebra last + i = $.inArray('zebra', c.widgets); + if (i >= 0) { + c.widgets.splice(i,1); + c.widgets.push('zebra'); + } + if (c.debug) { + time = new Date(); + } + // add selected widgets + for (i = 0; i < l; i++) { + w = ts.getWidgetById(ws[i]); + if ( w ) { + if (init === true && w.hasOwnProperty('init')) { + w.init(table, w, c, wo); + } else if (!init && w.hasOwnProperty('format')) { + w.format(table, c, wo); + } + } + } + if (c.debug) { + benchmark("Completed " + (init === true ? "initializing" : "applying") + " widgets", time); + } + }; + + ts.refreshWidgets = function(table, doAll, dontapply) { + var i, c = table.config, + cw = c.widgets, + w = ts.widgets, l = w.length; + // remove previous widgets + for (i = 0; i < l; i++){ + if ( w[i] && w[i].id && (doAll || $.inArray( w[i].id, cw ) < 0) ) { + if (c.debug) { log( 'removing ' + w[i].id ); } + if (w[i].hasOwnProperty('remove')) { w[i].remove(table, c, c.widgetOptions); } + } + } + if (dontapply !== true) { + ts.applyWidget(table, doAll); + } + }; + // get sorter, string, empty, etc options for each column from // jQuery data, metadata, header option or header class name ("sorter-false") // priority = jQuery data > meta > headers option > header class name - this.getData = function(h, ch, key) { + ts.getData = function(h, ch, key) { var val = '', $h = $(h), m, cl; if (!$h.length) { return ''; } m = $.metadata ? $h.metadata() : false; cl = ' ' + ($h.attr('class') || ''); - if ($h.data() && ( typeof $h.data(key) !== 'undefined' || typeof $h.data(key.toLowerCase()) !== 'undefined') ){ + if (typeof $h.data(key) !== 'undefined' || typeof $h.data(key.toLowerCase()) !== 'undefined'){ // "data-lockedOrder" is assigned to "lockedorder"; but "data-locked-order" is assigned to "lockedOrder" // "data-sort-initial-order" is assigned to "sortInitialOrder" val += $h.data(key) || $h.data(key.toLowerCase()); @@ -969,19 +1098,39 @@ val += m[key]; } else if (ch && typeof ch[key] !== 'undefined') { val += ch[key]; - } else if (cl && cl.match(' ' + key + '-')) { + } else if (cl !== ' ' && cl.match(' ' + key + '-')) { // include sorter class name "sorter-text", etc val = cl.match( new RegExp(' ' + key + '-(\\w+)') )[1] || ''; } return $.trim(val); }; - this.clearTableBody = function(table) { - $(table.tBodies).filter(':not(.' + table.config.cssInfoBlock + ')').empty(); + ts.formatFloat = function(s, table) { + if (typeof(s) !== 'string' || s === '') { return s; } + if (table.config.usNumberFormat !== false) { + // US Format - 1,234,567.89 -> 1234567.89 + 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,'.'); + } + if(/^\s*\([.\d]+\)/.test(s)) { + // make (#) into a negative number -> (10) = -10 + s = s.replace(/^\s*\(/,'-').replace(/\)/,''); + } + var i = parseFloat(s); + // return the text instead of zero + return isNaN(i) ? $.trim(s) : i; }; - } - })(); + ts.isDigit = function(s) { + // replace all unwanted chars and match + return isNaN(s) ? (/^[\-+(]?\d+[)]?$/).test(s.toString().replace(/[,.'\s]/g, '')) : true; + }; + + }() + }); // make shortcut var ts = $.tablesorter; @@ -1069,10 +1218,10 @@ ts.addParser({ id: "usLongDate", is: function(s) { - return s.match(/^[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)))$/); + return (/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4}|'?\d{2})\s+(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i).test(s); }, format: function(s, table) { - return ts.formatFloat( (new Date(s).getTime() || ''), table); + return ts.formatFloat( (new Date(s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || ''), table); }, type: "numeric" }); @@ -1106,10 +1255,10 @@ ts.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); + return (/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i).test(s); }, format: function(s, table) { - return ts.formatFloat( (new Date("2000/01/01 " + s).getTime() || ''), table); + return ts.formatFloat( (new Date("2000/01/01 " + s.replace(/(\S)([AP]M)$/i, "$1 $2")).getTime() || ""), table); }, type: "numeric" }); @@ -1141,15 +1290,10 @@ // add default widgets ts.addWidget({ id: "zebra", - format: function(table) { + format: function(table, c, wo) { var $tb, $tv, $tr, row, even, time, k, l, - c = table.config, child = new RegExp(c.cssChildRow, 'i'), - b = $(table).children('tbody:not(.' + c.cssInfoBlock + ')'), - css = [ "even", "odd" ]; - // maintain backwards compatibility - css = c.widgetZebra && c.hasOwnProperty('css') ? c.widgetZebra.css : - (c.widgetOptions && c.widgetOptions.hasOwnProperty('zebra')) ? c.widgetOptions.zebra : css; + b = $(table).children('tbody:not(.' + c.cssInfoBlock + ')'); if (c.debug) { time = new Date(); } @@ -1159,22 +1303,30 @@ l = $tb.children('tr').length; if (l > 1) { row = 0; - $tv = $tb.find('tr:visible'); - $tb.addClass('tablesorter-hidden'); + $tv = $tb.children('tr:visible'); // revered back to using jQuery each - strangely it's the fastest method $tv.each(function(){ $tr = $(this); // style children rows the same way the parent row was styled if (!child.test(this.className)) { row++; } even = (row % 2 === 0); - $tr.removeClass(css[even ? 1 : 0]).addClass(css[even ? 0 : 1]); + $tr.removeClass(wo.zebra[even ? 1 : 0]).addClass(wo.zebra[even ? 0 : 1]); }); - $tb.removeClass('tablesorter-hidden'); } } if (c.debug) { ts.benchmark("Applying Zebra widget", time); } + }, + remove: function(table, c, wo){ + var k, $tb, + b = $(table).children('tbody:not(.' + c.cssInfoBlock + ')'), + rmv = (c.widgetOptions.zebra || [ "even", "odd" ]).join(' '); + for (k = 0; k < b.length; k++ ){ + $tb = $.tablesorter.processTbody(table, $(b[k]), true); // remove tbody + $tb.children().removeClass(rmv); + $.tablesorter.processTbody(table, $tb, false); // restore tbody + } } }); diff --git a/sitestatic/jquery.tablesorter-2.4.5.min.js b/sitestatic/jquery.tablesorter-2.4.5.min.js new file mode 100644 index 0000000..a52ce35 --- /dev/null +++ b/sitestatic/jquery.tablesorter-2.4.5.min.js @@ -0,0 +1,6 @@ +/*! +* TableSorter 2.4.5 - Client-side table sorting with ease! +* Minified using UglifyJS (http://jscompress.com/) +* Copyright (c) 2007 Christian Bach +*/ +!function($){"use strict";$.extend({tablesorter:new function(){function log(a){if(typeof console!=="undefined"&&typeof console.log!=="undefined"){console.log(a)}else{alert(a)}}function benchmark(a,b){log(a+" ("+((new Date).getTime()-b.getTime())+"ms)")}function getElementText(a,b,c){if(!b){return""}var d=a.config,e=d.textExtraction,f="";if(e==="simple"){if(d.supportsTextContent){f=b.textContent}else{f=$(b).text()}}else{if(typeof e==="function"){f=e(b,a,c)}else if(typeof e==="object"&&e.hasOwnProperty(c)){f=e[c](b,a,c)}else{f=d.supportsTextContent?b.textContent:$(b).text()}}return $.trim(f)}function detectParserForColumn(a,b,c,d){var e,f=ts.parsers.length,g=false,h="",i=true;while(h===""&&i){c++;if(b[c]){g=b[c].cells[d];h=getElementText(a,g,d);if(a.config.debug){log("Checking if value was empty on row "+c+", column: "+d+": "+h)}}else{i=false}}for(e=1;e<f;e++){if(ts.parsers[e].is(h,a,g)){return ts.parsers[e]}}return ts.parsers[0]}function buildParserCache(a,b){var c=a.config,d=$(a.tBodies).filter(":not(."+c.cssInfoBlock+")"),e,f,g,h,i,j,k,l="";if(d.length===0){return}e=d[0].rows;if(e[0]){f=[];g=e[0].cells.length;for(h=0;h<g;h++){i=b.filter(':not([colspan])[data-column="'+h+'"]:last,[colspan="1"][data-column="'+h+'"]:last');j=c.headers[h];k=ts.getParserById(ts.getData(i,j,"sorter"));c.empties[h]=ts.getData(i,j,"empty")||c.emptyTo||(c.emptyToBottom?"bottom":"top");c.strings[h]=ts.getData(i,j,"string")||c.stringTo||"max";if(!k){k=detectParserForColumn(a,e,-1,h)}if(c.debug){l+="column:"+h+"; parser:"+k.id+"; string:"+c.strings[h]+"; empty: "+c.empties[h]+"\n"}f.push(k)}}if(c.debug){log(l)}return f}function buildCache(a){var b=a.tBodies,c=a.config,d,e,f=c.parsers,g,h,i,j,k,l,m;c.cache={};if(c.debug){m=new Date}if(c.showProcessing){ts.isProcessing(a,true)}for(j=0;j<b.length;j++){c.cache[j]={row:[],normalized:[]};if(!$(b[j]).hasClass(c.cssInfoBlock)){d=b[j]&&b[j].rows.length||0;e=b[j].rows[0]&&b[j].rows[0].cells.length||0;for(h=0;h<d;++h){k=$(b[j].rows[h]);l=[];if(k.hasClass(c.cssChildRow)){c.cache[j].row[c.cache[j].row.length-1]=c.cache[j].row[c.cache[j].row.length-1].add(k);continue}c.cache[j].row.push(k);for(i=0;i<e;++i){g=getElementText(a,k[0].cells[i],i);l.push(f[i].format(g,a,k[0].cells[i],i))}l.push(c.cache[j].normalized.length);c.cache[j].normalized.push(l)}}}if(c.showProcessing){ts.isProcessing(a)}if(c.debug){benchmark("Building cache for "+d+" rows",m)}}function appendToTable(a,b){var c=a.config,d=a.tBodies,e=[],f=c.cache,g,h,i,j,k,l,m,n,o,p,q,r;if(c.debug){r=new Date}for(o=0;o<d.length;o++){k=$(d[o]);if(!k.hasClass(c.cssInfoBlock)){l=ts.processTbody(a,k,true);g=f[o].row;h=f[o].normalized;i=h.length;j=i?h[0].length-1:0;for(m=0;m<i;m++){q=h[m][j];e.push(g[q]);if(!c.appender||!c.removeRows){p=g[q].length;for(n=0;n<p;n++){l.append(g[q][n])}}}ts.processTbody(a,l,false)}}if(c.appender){c.appender(a,e)}if(c.debug){benchmark("Rebuilt table",r)}if(!b){ts.applyWidget(a)}$(a).trigger("sortEnd",a)}function computeThIndexes(a){var b=[],c={},d=$(a).find("thead:eq(0) tr, tfoot tr"),e,f,g,h,i,j,k,l,m,n,o,p;for(e=0;e<d.length;e++){j=d[e].cells;for(f=0;f<j.length;f++){i=j[f];k=i.parentNode.rowIndex;l=k+"-"+i.cellIndex;m=i.rowSpan||1;n=i.colSpan||1;if(typeof b[k]==="undefined"){b[k]=[]}for(g=0;g<b[k].length+1;g++){if(typeof b[k][g]==="undefined"){o=g;break}}c[l]=o;$(i).attr({"data-column":o});for(g=k;g<k+m;g++){if(typeof b[g]==="undefined"){b[g]=[]}p=b[g];for(h=o;h<o+n;h++){p[h]="x"}}}}return c}function formatSortingOrder(a){return/^d/i.test(a)||a===1}function buildHeaders(a){var b=computeThIndexes(a),c,d,e,f,g,h,i=a.config;i.headerList=[];if(i.debug){g=new Date}h=$(a).find(i.selectorHeaders).each(function(a){d=$(this);c=i.headers[a];e=i.cssIcon?'<i class="'+i.cssIcon+'"></i>':"";this.innerHTML='<div class="tablesorter-header-inner">'+this.innerHTML+e+"</div>";if(i.onRenderHeader){i.onRenderHeader.apply(d,[a])}this.column=b[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=formatSortingOrder(ts.getData(d,c,"sortInitialOrder")||i.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;if(ts.getData(d,c,"sorter")==="false"){this.sortDisabled=true;d.addClass("sorter-false")}else{d.removeClass("sorter-false")}this.lockedOrder=false;f=ts.getData(d,c,"lockedOrder")||false;if(typeof f!=="undefined"&&f!==false){this.order=this.lockedOrder=formatSortingOrder(f)?[1,1,1]:[0,0,0]}d.addClass(this.sortDisabled?"sorter-false":i.cssHeader);i.headerList[a]=this;d.parent().addClass(i.cssHeaderRow)});if(a.config.debug){benchmark("Built headers:",g);log(h)}return h}function setHeadersCss(a,b){var c,d,e,f,g=a.config,h=g.sortList,i=[g.cssDesc,g.cssAsc],j=$(a).find("tfoot tr").children().removeClass(i.join(" "));b.removeClass(i.join(" "));f=h.length;for(d=0;d<f;d++){if(h[d][1]!==2){c=b.not(".sorter-false").filter('[data-column="'+h[d][0]+'"]'+(f===1?":last":""));if(c.length){for(e=0;e<c.length;e++){if(!c[e].sortDisabled){c.eq(e).addClass(i[h[d][1]]);if(j.length){j.filter('[data-column="'+h[d][0]+'"]').eq(e).addClass(i[h[d][1]])}}}}}}}function fixColumnWidth(a){if(a.config.widthFixed&&$(a).find("colgroup").length===0){var b=$("<colgroup>"),c=$(a).width();$("tr:first td",a.tBodies[0]).each(function(){b.append($("<col>").css("width",parseInt($(this).width()/c*1e3,10)/10+"%"))});$(a).prepend(b)}}function updateHeaderSortCount(a,b){var c,d,e=a.config,f=e.headerList.length,g=b||e.sortList;e.sortList=[];$.each(g,function(a,b){c=[parseInt(b[0],10),parseInt(b[1],10)];d=e.headerList[c[0]];if(d){e.sortList.push(c);d.count=c[1]%(e.sortReset?3:2)}})}function getCachedSortType(a,b){return a&&a[b]?a[b].type||"":""}function multisort(table){var dynamicExp,sortWrapper,col,mx=0,dir=0,tc=table.config,sortList=tc.sortList,l=sortList.length,bl=table.tBodies.length,sortTime,i,j,k,c,cache,lc,s,e,order,orgOrderCol;if(tc.debug){sortTime=new Date}for(k=0;k<bl;k++){dynamicExp="sortWrapper = function(a,b) {";cache=tc.cache[k];lc=cache.normalized.length;for(i=0;i<l;i++){c=sortList[i][0];order=sortList[i][1];s=/n/i.test(getCachedSortType(tc.parsers,c))?"Numeric":"Text";s+=order===0?"":"Desc";e="e"+i;if(/Numeric/.test(s)&&tc.strings[c]){for(j=0;j<lc;j++){col=Math.abs(parseFloat(cache.normalized[j][c]));mx=Math.max(mx,isNaN(col)?0:col)}if(typeof tc.string[tc.strings[c]]==="boolean"){dir=(order===0?1:-1)*(tc.string[tc.strings[c]]?-1:1)}else{dir=tc.strings[c]?tc.string[tc.strings[c]]||0:0}}dynamicExp+="var "+e+" = $.tablesorter.sort"+s+"(table,a["+c+"],b["+c+"],"+c+","+mx+","+dir+"); ";dynamicExp+="if ("+e+") { return "+e+"; } ";dynamicExp+="else { "}orgOrderCol=cache.normalized&&cache.normalized[0]?cache.normalized[0].length-1:0;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(i=0;i<l;i++){dynamicExp+="}; "}dynamicExp+="return 0; ";dynamicExp+="}; ";cache.normalized.sort(eval(dynamicExp))}if(tc.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time",sortTime)}}function resortComplete(a,b){var c=a[0];a.trigger("updateComplete");if(typeof b==="function"){b(c)}}function checkResort(a,b,c){if(b!==false){a.trigger("sorton",[a[0].config.sortList,function(){resortComplete(a,c)}])}else{resortComplete(a,c)}}var ts=this;ts.version="2.4.5";ts.parsers=[];ts.widgets=[];ts.defaults={theme:"default",widthFixed:false,showProcessing:false,cancelSelection:true,dateFormat:"mmddyyyy",sortMultiSortKey:"shiftKey",usNumberFormat:true,delayInit:false,headers:{},ignoreCase:true,sortForce:null,sortList:[],sortAppend:null,sortInitialOrder:"asc",sortLocaleCompare:false,sortReset:false,sortRestart:false,emptyTo:"bottom",stringTo:"max",textExtraction:"simple",textSorter:null,widgets:[],widgetOptions:{zebra:["even","odd"]},initWidgets:true,initialized:null,onRenderHeader:null,tableClass:"tablesorter",cssAsc:"tablesorter-headerSortUp",cssChildRow:"tablesorter-childRow",cssDesc:"tablesorter-headerSortDown",cssHeader:"tablesorter-header",cssHeaderRow:"tablesorter-headerRow",cssIcon:"tablesorter-icon",cssInfoBlock:"tablesorter-infoOnly",cssProcessing:"tablesorter-processing",selectorHeaders:"> thead th, > thead td",selectorSort:"th, td",selectorRemove:".remove-me",debug:false,headerList:[],empties:{},strings:{},parsers:[]};ts.benchmark=benchmark;ts.construct=function(a){return this.each(function(){if(!this.tHead||this.tBodies.length===0||this.hasInitialized===true){return}var b,c,d=$(this),e,f,g,h="",i,j,k,l,m=$.metadata;this.hasInitialized=false;this.config={};e=$.extend(true,this.config,ts.defaults,a);$.data(this,"tablesorter",e);if(e.debug){$.data(this,"startoveralltimer",new Date)}e.supportsTextContent=$("<span>x</span>")[0].textContent==="x";e.supportsDataObject=parseFloat($.fn.jquery)>=1.4;e.string={max:1,min:-1,"max+":1,"max-":-1,zero:0,none:0,"null":0,top:true,bottom:false};if(!/tablesorter\-/.test(d.attr("class"))){h=e.theme!==""?" tablesorter-"+e.theme:""}d.addClass(e.tableClass+h);b=buildHeaders(this);e.parsers=buildParserCache(this,b);if(!e.delayInit){buildCache(this)}b.find("*").andSelf().filter(e.selectorSort).unbind("mousedown.tablesorter mouseup.tablesorter").bind("mousedown.tablesorter mouseup.tablesorter",function(a,c){var m=this.tagName.match("TH|TD")?$(this):$(this).parents("th, td").filter(":last"),n=m[0];if((a.which||a.button)!==1){return false}if(a.type==="mousedown"){l=(new Date).getTime();return a.target.tagName==="INPUT"?"":!e.cancelSelection}if(c!==true&&(new Date).getTime()-l>250){return false}if(e.delayInit&&!e.cache){buildCache(d[0])}if(!n.sortDisabled){d.trigger("sortStart",d[0]);h=!a[e.sortMultiSortKey];n.count=(n.count+1)%(e.sortReset?3:2);if(e.sortRestart){f=n;b.each(function(){if(this!==f&&(h||!$(this).is("."+e.cssDesc+",."+e.cssAsc))){this.count=-1}})}f=n.column;if(h){e.sortList=[];if(e.sortForce!==null){i=e.sortForce;for(g=0;g<i.length;g++){if(i[g][0]!==f){e.sortList.push(i[g])}}}k=n.order[n.count];if(k<2){e.sortList.push([f,k]);if(n.colSpan>1){for(g=1;g<n.colSpan;g++){e.sortList.push([f+g,k])}}}}else{if(e.sortAppend&&e.sortList.length>1){if(ts.isValueInArray(e.sortAppend[0][0],e.sortList)){e.sortList.pop()}}if(ts.isValueInArray(f,e.sortList)){for(g=0;g<e.sortList.length;g++){j=e.sortList[g];k=e.headerList[j[0]];if(j[0]===f){j[1]=k.order[k.count];if(j[1]===2){e.sortList.splice(g,1);k.count=-1}}}}else{k=n.order[n.count];if(k<2){e.sortList.push([f,k]);if(n.colSpan>1){for(g=1;g<n.colSpan;g++){e.sortList.push([f+g,k])}}}}}if(e.sortAppend!==null){i=e.sortAppend;for(g=0;g<i.length;g++){if(i[g][0]!==f){e.sortList.push(i[g])}}}d.trigger("sortBegin",d[0]);setTimeout(function(){setHeadersCss(d[0],b);multisort(d[0]);appendToTable(d[0])},1)}});if(e.cancelSelection){b.each(function(){this.onselectstart=function(){return false}})}d.unbind("update updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave").bind("update",function(a,c,f){$(e.selectorRemove,this).remove();e.parsers=buildParserCache(this,b);buildCache(this);checkResort(d,c,f)}).bind("updateCell",function(a,b,c,f){var g,h,i,j=this,k=$(this).find("tbody"),l=k.index($(b).parents("tbody").filter(":last")),m=$(b).parents("tr").filter(":last");if(k.length&&l>=0){h=k.eq(l).find("tr").index(m);i=b.cellIndex;g=j.config.cache[l].normalized[h].length-1;j.config.cache[l].row[j.config.cache[l].normalized[h][g]]=m;j.config.cache[l].normalized[h][i]=e.parsers[i].format(getElementText(j,b,i),j,b,i);checkResort(d,c,f)}}).bind("addRows",function(a,b,c,f){var h,i=b.filter("tr").length,j=[],k=b[0].cells.length,l=this,m=$(this).find("tbody").index(b.closest("tbody"));for(h=0;h<i;h++){for(g=0;g<k;g++){j[g]=e.parsers[g].format(getElementText(l,b[h].cells[g],g),l,b[h].cells[g],g)}j.push(e.cache[m].row.length);e.cache[m].row.push([b[h]]);e.cache[m].normalized.push(j);j=[]}checkResort(d,c,f)}).bind("sorton",function(a,c,d,e){$(this).trigger("sortStart",this);updateHeaderSortCount(this,c);setHeadersCss(this,b);multisort(this);appendToTable(this,e);if(typeof d==="function"){d(this)}}).bind("appendCache",function(a,b,c){appendToTable(this,c);if(typeof b==="function"){b(this)}}).bind("applyWidgetId",function(a,b){ts.getWidgetById(b).format(this,e,e.widgetOptions)}).bind("applyWidgets",function(a,b){ts.applyWidget(this,b)}).bind("refreshWidgets",function(a,b,c){ts.refreshWidgets(this,b,c)}).bind("destroy",function(a,b,c){ts.destroy(this,b,c)});if(e.supportsDataObject&&typeof d.data().sortlist!=="undefined"){e.sortList=d.data().sortlist}else if(m&&d.metadata()&&d.metadata().sortlist){e.sortList=d.metadata().sortlist}ts.applyWidget(this,true);if(e.sortList.length>0){d.trigger("sorton",[e.sortList,{},!e.initWidgets])}else if(e.initWidgets){ts.applyWidget(this)}fixColumnWidth(this);if(e.showProcessing){d.unbind("sortBegin sortEnd").bind("sortBegin sortEnd",function(a){ts.isProcessing(d[0],a.type==="sortBegin")})}this.hasInitialized=true;if(e.debug){ts.benchmark("Overall initialization time",$.data(this,"startoveralltimer"))}d.trigger("tablesorter-initialized",this);if(typeof e.initialized==="function"){e.initialized(this)}})};ts.isProcessing=function(a,b,c){var d=a.config,e=c||$(a).find("."+d.cssHeader);if(b){if(d.sortList.length>0){e=e.filter(function(){return this.sortDisabled?false:ts.isValueInArray(parseFloat($(this).attr("data-column")),d.sortList)})}e.addClass(d.cssProcessing)}else{e.removeClass(d.cssProcessing)}};ts.processTbody=function(a,b,c){var d,e;if(c){b.before('<span class="tablesorter-savemyplace"/>');e=$.fn.detach?b.detach():b.remove();return e}e=$(a).find("span.tablesorter-savemyplace");b.insertAfter(e);e.remove()};ts.clearTableBody=function(a){$(a.tBodies).filter(":not(."+a.config.cssInfoBlock+")").empty()};ts.destroy=function(a,b,c){var d=$(a),e=a.config,f=d.find("thead:first");a.hasInitialized=false;f.find("tr:not(."+e.cssHeaderRow+")").remove();f.find(".tablesorter-resizer").remove();ts.refreshWidgets(a,true,true);d.removeData("tablesorter").unbind("update updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave").find("."+e.cssHeader).unbind("click mousedown mousemove mouseup").removeClass(e.cssHeader+" "+e.cssAsc+" "+e.cssDesc).find(".tablesorter-header-inner").each(function(){if(e.cssIcon!==""){$(this).find("."+e.cssIcon).remove()}$(this).replaceWith($(this).contents())});if(b!==false){d.removeClass(e.tableClass)}if(typeof c==="function"){c(a)}};ts.regex=[/(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,/^0x[0-9a-f]+$/i];ts.sortText=function(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo],g=ts.regex,h,i,j,k,l,m,n,o;if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:-f||-1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:f||1}if(typeof e.textSorter==="function"){return e.textSorter(b,c,a,d)}h=b.replace(g[0],"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");j=c.replace(g[0],"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");i=parseInt(b.match(g[2]),16)||h.length!==1&&b.match(g[1])&&Date.parse(b);k=parseInt(c.match(g[2]),16)||i&&c.match(g[1])&&Date.parse(c)||null;if(k){if(i<k){return-1}if(i>k){return 1}}o=Math.max(h.length,j.length);for(n=0;n<o;n++){l=isNaN(h[n])?h[n]||0:parseFloat(h[n])||0;m=isNaN(j[n])?j[n]||0:parseFloat(j[n])||0;if(isNaN(l)!==isNaN(m)){return isNaN(l)?1:-1}if(typeof l!==typeof m){l+="";m+=""}if(l<m){return-1}if(l>m){return 1}}return 0};ts.sortTextDesc=function(a,b,c,d){if(b===c){return 0}var e=a.config,f=e.string[e.empties[d]||e.emptyTo];if(b===""&&f!==0){return typeof f==="boolean"?f?-1:1:f||1}if(c===""&&f!==0){return typeof f==="boolean"?f?1:-1:-f||-1}if(typeof e.textSorter==="function"){return e.textSorter(c,b,a,d)}return ts.sortText(a,c,b)};ts.getTextValue=function(a,b,c){if(b){var d,e=a.length,f=b+c;for(d=0;d<e;d++){f+=a.charCodeAt(d)}return c*f}return 0};ts.sortNumeric=function(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:-h||-1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:h||1}if(isNaN(b)){b=ts.getTextValue(b,e,f)}if(isNaN(c)){c=ts.getTextValue(c,e,f)}return b-c};ts.sortNumericDesc=function(a,b,c,d,e,f){if(b===c){return 0}var g=a.config,h=g.string[g.empties[d]||g.emptyTo];if(b===""&&h!==0){return typeof h==="boolean"?h?-1:1:h||1}if(c===""&&h!==0){return typeof h==="boolean"?h?1:-1:-h||-1}if(isNaN(b)){b=ts.getTextValue(b,e,f)}if(isNaN(c)){c=ts.getTextValue(c,e,f)}return c-b};ts.characterEquivalents={a:"\u00e1\u00e0\u00e2\u00e3\u00e4",A:"\u00c1\u00c0\u00c2\u00c3\u00c4",c:"\u00e7",C:"\u00c7",e:"\u00e9\u00e8\u00ea\u00eb",E:"\u00c9\u00c8\u00ca\u00cb",i:"\u00ed\u00ec\u0130\u00ee\u00ef",I:"\u00cd\u00cc\u0130\u00ce\u00cf",o:"\u00f3\u00f2\u00f4\u00f5\u00f6",O:"\u00d3\u00d2\u00d4\u00d5\u00d6",S:"\u00df",u:"\u00fa\u00f9\u00fb\u00fc",U:"\u00da\u00d9\u00db\u00dc"};ts.replaceAccents=function(a){var b,c="[",d=ts.characterEquivalents;if(!ts.characterRegex){ts.characterRegexArray={};for(b in d){if(typeof b==="string"){c+=d[b];ts.characterRegexArray[b]=new RegExp("["+d[b]+"]","g")}}ts.characterRegex=new RegExp(c+"]")}if(ts.characterRegex.test(a)){for(b in d){if(typeof b==="string"){a=a.replace(ts.characterRegexArray[b],b)}}}return a};ts.isValueInArray=function(a,b){var c,d=b.length;for(c=0;c<d;c++){if(b[c][0]===a){return true}}return false};ts.addParser=function(a){var b,c=ts.parsers.length,d=true;for(b=0;b<c;b++){if(ts.parsers[b].id.toLowerCase()===a.id.toLowerCase()){d=false}}if(d){ts.parsers.push(a)}};ts.getParserById=function(a){var b,c=ts.parsers.length;for(b=0;b<c;b++){if(ts.parsers[b].id.toLowerCase()===a.toString().toLowerCase()){return ts.parsers[b]}}return false};ts.addWidget=function(a){ts.widgets.push(a)};ts.getWidgetById=function(a){var b,c,d=ts.widgets.length;for(b=0;b<d;b++){c=ts.widgets[b];if(c&&c.hasOwnProperty("id")&&c.id.toLowerCase()===a.toLowerCase()){return c}}};ts.applyWidget=function(a,b){var c=a.config,d=c.widgetOptions,e=c.widgets.sort().reverse(),f,g,h,i=e.length;g=$.inArray("zebra",c.widgets);if(g>=0){c.widgets.splice(g,1);c.widgets.push("zebra")}if(c.debug){f=new Date}for(g=0;g<i;g++){h=ts.getWidgetById(e[g]);if(h){if(b===true&&h.hasOwnProperty("init")){h.init(a,h,c,d)}else if(!b&&h.hasOwnProperty("format")){h.format(a,c,d)}}}if(c.debug){benchmark("Completed "+(b===true?"initializing":"applying")+" widgets",f)}};ts.refreshWidgets=function(a,b,c){var d,e=a.config,f=e.widgets,g=ts.widgets,h=g.length;for(d=0;d<h;d++){if(g[d]&&g[d].id&&(b||$.inArray(g[d].id,f)<0)){if(e.debug){log("removing "+g[d].id)}if(g[d].hasOwnProperty("remove")){g[d].remove(a,e,e.widgetOptions)}}}if(c!==true){ts.applyWidget(a,b)}};ts.getData=function(a,b,c){var d="",e=$(a),f,g;if(!e.length){return""}f=$.metadata?e.metadata():false;g=" "+(e.attr("class")||"");if(typeof e.data(c)!=="undefined"||typeof e.data(c.toLowerCase())!=="undefined"){d+=e.data(c)||e.data(c.toLowerCase())}else if(f&&typeof f[c]!=="undefined"){d+=f[c]}else if(b&&typeof b[c]!=="undefined"){d+=b[c]}else if(g!==" "&&g.match(" "+c+"-")){d=g.match(new RegExp(" "+c+"-(\\w+)"))[1]||""}return $.trim(d)};ts.formatFloat=function(a,b){if(typeof a!=="string"||a===""){return a}if(b.config.usNumberFormat!==false){a=a.replace(/,/g,"")}else{a=a.replace(/[\s|\.]/g,"").replace(/,/g,".")}if(/^\s*\([.\d]+\)/.test(a)){a=a.replace(/^\s*\(/,"-").replace(/\)/,"")}var c=parseFloat(a);return isNaN(c)?$.trim(a):c};ts.isDigit=function(a){return isNaN(a)?/^[\-+(]?\d+[)]?$/.test(a.toString().replace(/[,.'\s]/g,"")):true}}});var ts=$.tablesorter;$.fn.extend({tablesorter:ts.construct});ts.addParser({id:"text",is:function(a,b,c){return true},format:function(a,b,c,d){var e=b.config;a=$.trim(e.ignoreCase?a.toLocaleLowerCase():a);return e.sortLocaleCompare?ts.replaceAccents(a):a},type:"text"});ts.addParser({id:"currency",is:function(a){return/^\(?[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"ipAddress",is:function(a){return/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/.test(a)},format:function(a,b){var c,d=a.split("."),e="",f=d.length;for(c=0;c<f;c++){e+=("00"+d[c]).slice(-3)}return ts.formatFloat(e,b)},type:"numeric"});ts.addParser({id:"url",is:function(a){return/^(https?|ftp|file):\/\//.test(a)},format:function(a){return $.trim(a.replace(/(https?|ftp|file):\/\//,""))},type:"text"});ts.addParser({id:"isoDate",is:function(a){return/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},format:function(a,b){return ts.formatFloat(a!==""?(new Date(a.replace(/-/g,"/"))).getTime()||"":"",b)},type:"numeric"});ts.addParser({id:"percent",is:function(a){return/\d%\)?$/.test(a)},format:function(a,b){return ts.formatFloat(a.replace(/%/g,""),b)},type:"numeric"});ts.addParser({id:"usLongDate",is:function(a){return/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4}|'?\d{2})\s+(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i.test(a)},format:function(a,b){return ts.formatFloat((new Date(a.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||"",b)},type:"numeric"});ts.addParser({id:"shortDate",is:function(a){return/^(\d{2}|\d{4})[\/\-\,\.\s+]\d{2}[\/\-\.\,\s+](\d{2}|\d{4})$/.test(a)},format:function(a,b,c,d){var e=b.config,f=e.headerList[d],g=f.shortDateFormat;if(typeof g==="undefined"){g=f.shortDateFormat=ts.getData(f,e.headers[d],"dateFormat")||e.dateFormat}a=a.replace(/\s+/g," ").replace(/[\-|\.|\,]/g,"/");if(g==="mmddyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2")}else if(g==="ddmmyyyy"){a=a.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1")}else if(g==="yyyymmdd"){a=a.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/,"$1/$2/$3")}return ts.formatFloat((new Date(a)).getTime()||"",b)},type:"numeric"});ts.addParser({id:"time",is:function(a){return/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i.test(a)},format:function(a,b){return ts.formatFloat((new Date("2000/01/01 "+a.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||"",b)},type:"numeric"});ts.addParser({id:"digit",is:function(a){return ts.isDigit(a)},format:function(a,b){return ts.formatFloat(a.replace(/[^\w,. \-()]/g,""),b)},type:"numeric"});ts.addParser({id:"metadata",is:function(a){return false},format:function(a,b,c){var d=b.config,e=!d.parserMetadataName?"sortValue":d.parserMetadataName;return $(c).metadata()[e]},type:"numeric"});ts.addWidget({id:"zebra",format:function(a,b,c){var d,e,f,g,h,i,j,k,l=new RegExp(b.cssChildRow,"i"),m=$(a).children("tbody:not(."+b.cssInfoBlock+")");if(b.debug){i=new Date}for(j=0;j<m.length;j++){d=$(m[j]);k=d.children("tr").length;if(k>1){g=0;e=d.children("tr:visible");e.each(function(){f=$(this);if(!l.test(this.className)){g++}h=g%2===0;f.removeClass(c.zebra[h?1:0]).addClass(c.zebra[h?0:1])})}}if(b.debug){ts.benchmark("Applying Zebra widget",i)}},remove:function(a,b,c){var d,e,f=$(a).children("tbody:not(."+b.cssInfoBlock+")"),g=(b.widgetOptions.zebra||["even","odd"]).join(" ");for(d=0;d<f.length;d++){e=$.tablesorter.processTbody(a,$(f[d]),true);e.children().removeClass(g);$.tablesorter.processTbody(a,e,false)}}})}(jQuery) |