/* Table sorting script by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/. Based on a script from http://www.kryogenix.org/code/browser/sorttable/. Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html . Copyright (c) 1997-2007 Stuart Langridge, Joost de Valk. Version 1.5.7 -- modified for PmWiki Attachtable by Eemeli Aro <eemeli@gmail.com> */ var arrow_up = ' ▴'; var arrow_down = ' ▾'; var arrow_none = ' '; var SORT_COLUMN_INDEX; var thead = false; if (window.addEventListener) window.addEventListener( 'load', sortables_init, false ); else if (window.attachEvent) window.attachEvent( 'onload', sortables_init ); function sortables_init() { if (!document.getElementsByTagName) return; tbls = document.getElementsByTagName("table"); for (ti=0;ti<tbls.length;ti++) { thisTbl = tbls[ti]; if ( (' '+thisTbl.className+' ').indexOf("sortable") != -1) { ts_makeSortable(thisTbl); } } } function ts_makeSortable(t) { if (t.rows && t.rows.length > 0) { if (t.tHead && t.tHead.rows.length > 0) { var firstRow = t.tHead.rows[t.tHead.rows.length-1]; thead = true; } else { var firstRow = t.rows[0]; } } if (!firstRow) return; for (var i=0;i<firstRow.cells.length;i++) { var cell = firstRow.cells[i]; var txt = ts_getInnerText(cell); if (cell.className != "unsortable" && cell.className.indexOf("unsortable") == -1) { cell.innerHTML = '<a href="#" class="sortheader" style="cursor:s-resize;" onclick="ts_resortTable(this, '+i+');return false;">'+txt+'<span class="sortarrow">'+ arrow_none + '</span></a>'; } } } function ts_getInnerText(el) { if (typeof el == "string") return el; if (typeof el == "undefined") { return el }; if (el.getAttribute('sortval')) return el.getAttribute('sortval'); if (el.innerText) return el.innerText; //Not needed but it is faster var str = ""; var cs = el.childNodes; var l = cs.length; for (var i = 0; i < l; i++) switch (cs[i].nodeType) { case 1: //ELEMENT_NODE str += ts_getInnerText(cs[i]); break; case 3: //TEXT_NODE str += cs[i].nodeValue; break; } return str; } function ts_resortTable(lnk, clid) { var span; for (var ci=0;ci<lnk.childNodes.length;ci++) { if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') span = lnk.childNodes[ci]; } var spantext = ts_getInnerText(span); var td = lnk.parentNode; var column = clid || td.cellIndex; var t = getParent(td,'TABLE'); // Work out a type for the column if (t.rows.length <= 1) return; var itm = ""; var i = 0; while (itm == "" && i < t.tBodies[0].rows.length) { var itm = ts_getInnerText(t.tBodies[0].rows[i].cells[column]); itm = itm.replace(/^\s+|\s+$/g, ""); if (itm.substr(0,4) == "<!--" || itm.length == 0) { itm = ""; } i++; } if (itm == "") return; sortfn = ts_sort_caseinsensitive; if (itm.match(/^-?[£$€Û¢Ž]\d/)) sortfn = ts_sort_numeric; if (itm.match(/^-?(\d+[,\.]?)+(E[-+][\d]+)?%?$/)) sortfn = ts_sort_numeric; SORT_COLUMN_INDEX = column; var firstRow = new Array(); var newRows = new Array(); for (k=0;k<t.tBodies.length;k++) { for (i=0;i<t.tBodies[k].rows[0].length;i++) { firstRow[i] = t.tBodies[k].rows[0][i]; } } for (k=0;k<t.tBodies.length;k++) { if (!thead) { for (j=1;j<t.tBodies[k].rows.length;j++) newRows[j-1] = t.tBodies[k].rows[j]; } else { for (j=0;j<t.tBodies[k].rows.length;j++) newRows[j] = t.tBodies[k].rows[j]; } } newRows.sort(sortfn); if (span.getAttribute("sortdir") == 'down') { ARROW = arrow_up; newRows.reverse(); span.setAttribute('sortdir','up'); lnk.style.cursor = 's-resize'; } else { ARROW = arrow_down; span.setAttribute('sortdir','down'); lnk.style.cursor = 'n-resize'; } // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones // don't do sortbottom rows for (i=0; i<newRows.length; i++) { if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) { t.tBodies[0].appendChild(newRows[i]); } } // do sortbottom rows only for (i=0; i<newRows.length; i++) { if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1)) t.tBodies[0].appendChild(newRows[i]); } // Delete any other arrows there may be showing var allspans = document.getElementsByTagName("span"); for (var ci=0;ci<allspans.length;ci++) { if (allspans[ci].className == 'sortarrow') { if (getParent(allspans[ci],"table") == getParent(lnk,"table")) { // in the same table as us? allspans[ci].innerHTML = arrow_none; } } } span.innerHTML = ARROW; } function getParent(el, pTagName) { if (el == null) { return null; } else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) { return el; } else { return getParent(el.parentNode, pTagName); } } function ts_sort_numeric(a,b) { var aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^-?0-9.]/g,''); var bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^-?0-9.]/g,''); return compare_numeric(aa,bb); } function compare_numeric(a,b) { var aa = parseFloat(a); aa = (isNaN(aa) ? 0 : aa); var bb = parseFloat(b); bb = (isNaN(bb) ? 0 : bb); return aa - bb; } function ts_sort_caseinsensitive(a,b) { var aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase(); var bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase(); if (aa==bb) return 0; if (aa<bb) return -1; return 1; } function ts_sort_default(a,b) { aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]); bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]); if (aa==bb) return 0; if (aa<bb) return -1; return 1; }