//
// Sortable tables script (by Grauw)
// ======================
// Using standard DOM methods working in an XHTML environment.
//
// License: Public Domain (but feel free to mention my name ;))
//
// Usage:
// * Include the script in your document head:
// * Put xmlns:g="http://www.grauw.nl/g" on your document tag (or elsewhere in scope).
// * Put the attribute g:sort="yes" on all
tags you want to sort the column of.
// * Put onload="registerSort();" on your tag.
//
// Notes:
// * The g:sort attribute also accepts 'asc' and 'desc' as values, indicating the initial sort order.
// * The sort-text must be direct children of the table cells.
// * The script doesn't take colspan in account
// * This makes the page not validate anymore. Adding to the !DOCTYPE is possible, but cumbersome and
// pretty involved. The XHTML spec acknowledges this, but says work to address that is in progress.
// Personally, I suggest not to bother with it, and accept that the page is formally invalid.
// DTDs don't work well with namespaces anyway.
//
ns_g = "http://www.grauw.nl/g";
//
// Registers sort handler
//
function registerSort() {
// check if browser supports the script
var elem = document.documentElement;
if (elem.hasAttributeNS && elem.getAttributeNS && elem.setAttributeNS &&
elem.addEventListener && elem.replaceChild) {
var x = document.getElementsByTagName('th');
for (var i=0; i < x.length; i++) {
if (x[i].hasAttributeNS(ns_g, 'sort')) {
x[i].addEventListener("click", doSort, false);
x[i].style.cursor = 'pointer';
if (!x[i].hasAttribute('title')) {
x[i].setAttribute('title','Click to sort');
}
}
}
} else {
window.status = "This page has sortable tables, however this browser does not support it. Get Firefox, Mozilla or Opera 8 for this functionality.";
}
}
function hasAttributeNS(obj, ns, attr) {
if (x[i].hasAttributeNS) {
return x[i].hasAttributeNS(ns_g, 'sort');
} else {
return x[i].hasAttribute('g:sort');
}
}
//
// Function which is triggered when a sortable table head is clicked
//
function doSort(e) {
var curelem = e.currentTarget;
var asc;
if (curelem.getAttributeNS(ns_g, 'sort') != 'desc') {
asc = true;
curelem.setAttributeNS(ns_g, 'sort', 'desc');
} else {
asc = false;
curelem.setAttributeNS(ns_g, 'sort', 'asc');
}
var sortpos = getElemPosition(curelem);
// Find containing table element
var table = curelem.parentNode;
while (table.nodeName != 'table') {
table = table.parentNode;
}
var sortlist = getSortList(table, sortpos);
var oldlist = getSortList(table, sortpos);
if (asc) sortlist.sort(doCompareElem);
else sortlist.sort(doCompareElemDesc);
for (var i=0; i < sortlist.length; i++) {
oldlist[i].parentNode.parentNode.replaceChild(
sortlist[i].parentNode.cloneNode(true),
oldlist[i].parentNode
);
}
}
//
// Retrieves the position of the given element within its parent
// @param1 = element node
//
function getElemPosition(elem) {
var s = elem.parentNode.childNodes;
var a = 0;
for (var i=0; i < s.length; i++) {
if (s[i] == elem) return a;
if (s[i].nodeType == Node.ELEMENT_NODE) a++;
}
}
//
// Gets a list of the td's to be sorted
// @param1 = table node
// @param2 = column nr. to sort
//
function getSortList(table, sortpos) {
// if | is present, only sort elements inside ...
if (table.getElementsByTagName('tbody').length > 0)
table = table.getElementsByTagName('tbody')[0];
var s = table.getElementsByTagName('tr');
var nodelist = new Array();
var nodelistpos = 0;
for (var i=0; i < s.length; i++) {
var a = 0;
var p = s[i].childNodes;
for (var j=0; j text2) return 1;
else return -1;
}
//
// Same as above, but reverse order
//
function doCompareElemDesc(a, b) {
return doCompareElem(b, a);
}
//
// This function retrieves the text inside an element, for comparison.
//
function getTextForCompare(elem) {
return elem.innerHTML.replace(/<.*?>/g, '');
}