//======
//======
//
// Template- TABLE_SORT_JS.IHT by S.Huang 07-MAR-05 / 27-NOV-06
//
// Purpose-
//
// javascript functions to support table sorting
//
// Notes-
//
// - This script must be included in header of templates that
// have tables with class="sortable_table" to be sorted.
// - Items within and
are not sorted
// - Requires W3C DOM and Javascript 1.5 compliant browsers
// (also works on IE 5.x which is not fully compliant).
// - TH> note: I suspect the restriction to 1.5 had more
// to do with the DOM support, which is not explicitly
// tied to the version of Javascript. We test for DOM
// support by testing the required DOM functionality
// directly, as per industry standard.
//
// - Table must be in standard format:
//
//
//
// | col1 | ...
//
//
// ...
//
//
//
// - Currently, the element is not supported.
//
// Modifications-
//
// 18-APR-05 SH / TH / KB 4=17168
// - Created.
//
// 26-APR-05 SH / SH / KB 4=17168
// - Treat number string starting with '0' as a decimal number.
//
// 6-MAY-05 SH / SH / SH 17=
// - Correct a typo for function call getFullYear().
//
// 5-MAY-06 SH / JY / SH 17=
// - Supported float point sorting.
//
// 9-AUG-06 TH / SZ / TH 4=18545
// - Update search for sortable_table class attribute so that
// it works on all browsers.
// - Add workaround for Safari sometimes returning the #text node
// as the target of the event.
//
// 10-AUG-06 TH / BH / TH 17=
// - Fix date compare to work on non-IE browsers, which do not
// accept ", undefined" being passed as the hour component.
// - Allow single digit dates to be specified without a
// leading 0.
// - Explicitly exclude < javascript 1.2 so we don't have to test
// for the existance of RegExp wherever we use it.
// - Explicitly exclude browsers without minimum basic DOM support
// by testing for getElementsByTagName.
// - Use various standardized cross-browser event handling
// facilities from event_js.iht.
//
// 22-AUG-06 TH / BH / HD 17=18635
// - Correct compare to sort on the actual text node, rather
// than all the contents of the array passed in.
// - Correct compare to sort alphabetically if there are any
// alphabetic characters in any elements in the column
// being sorted.
//
// 27-NOV-06 TH / BH / TH 4=18616
// - Update getDateStr to drop the comma output before
// the hh:mm field, as it is apparently unnecessary and
// Safari has problems parsing it.
//
// 04-Jul-07 BG / BG / BG 12=18420
// - Converted to from .iht to .js.
//
//======
//======
// - The table comparison was originally implemented by Paul Sowden.
// - Some modifications have been added for Medianet specific purposes.
var prjNum="134";
var sortCount = new Array();
// - Alphabetic compare is case insensitive.
function compare(a,b) {
var au = new String(a[0]);
var bu = new String(b[0]);
// - parseFloat will read the first number in the
// string, so "92 Hal" would return 92. In this case,
// since there are alphabetic characters present,
// alphaCharsInCol will be set.
// - Strings starting with a number followed by non
// alphabetic characters will currently be sorted
// only based on the starting number.
var an = 0;
var bn = 0;
if (!alphaCharsInCol) {
an = parseFloat(au);
bn = parseFloat(bu);
}
if ( alphaCharsInCol || isNaN(an) || isNaN(bn)) {
if(isDate(au) && isDate(bu)) {
var dateStr1=getDateStr(au);
var dateStr2=getDateStr(bu);
var date1 = new Date(dateStr1);
var date2 = new Date(dateStr2);
return date1-date2;
} else {
var as = au.toLowerCase();
var bs = bu.toLowerCase();
if (as > bs) {
return 1;
} else {
return -1;
}
}
} else {
return an - bn;
}
}
// The date on Medianet tables is in format of "Mon dd {yyyy}{hh:mm}"
var regDate=/^\s*(\w{3}\s+\d{1,2})\s*(\d{4})?\s*(\d{1,2}:\d{1,2})?/;
function isDate(str) {
if(str.search(regDate) != -1) {
return true;
} else {
return false;
}
}
function getDateStr(str) {
var re = new RegExp(regDate);
var match = re.exec(str);
if (match[2] == "" || match[2] == undefined) {
if(prjNum=="029") {
match[2]="1983";
} else {
Today = new Date();
match[2]=Today.getFullYear().toString();
}
}
// Construct date string in format "Mon dd, yyyy hh:mm" which is
// recognized by the Date constructor.
var finalDate = match[1] + ", " + match[2];
if (match[3] != "" && match[3] != undefined) {
finalDate += " " + match[3];
}
return finalDate;
}
// DOM table sorter borrowed (but modified) from Paul Sowden
// Finally somone that does it the right way
// function borrowed from those lovely people at the w3c
function getConcatenedTextContent(node) {
var _result = "";
if (node == null) {
return _result;
}
var childrens = node.childNodes;
var i = 0;
while (i < childrens.length) {
var child = childrens.item(i);
switch (child.nodeType) {
case 1: // ELEMENT_NODE
case 5: // ENTITY_REFERENCE_NODE
_result += getConcatenedTextContent(child);
break;
case 3: // TEXT_NODE
case 2: // ATTRIBUTE_NODE
case 4: // CDATA_SECTION_NODE
_result += child.nodeValue;
break;
case 6: // ENTITY_NODE
case 7: // PROCESSING_INSTRUCTION_NODE
case 8: // COMMENT_NODE
case 9: // DOCUMENT_NODE
case 10: // DOCUMENT_TYPE_NODE
case 11: // DOCUMENT_FRAGMENT_NODE
case 12: // NOTATION_NODE
// skip
break;
}
i ++;
}
return _result;
}
var alphaCharsInCol;
function sort(e) {
// Skip if the necessary level of DOM support isn't present.
if (!document.getElementsByTagName) return;
// - We can't pass extra arguments to the compare routine, as its
// just a function pointer of a constrained type.
// - We want to ensure if there are any alphabetic entries in
// the current column, an alphabetic sort is used, but compare
// can only compare the current 2 items being sorted.
// - Thus, we signal whether to use an alphabetic sort from
// the outside.
alphaCharsInCol = false;
var ev = dy_get_event(e);
var el = dy_get_event_target(ev);
var a = new Array();
var name = el.firstChild.nodeValue;
var dad = el.parentNode;
var node;
var colInx;
// Determine which column we are sorting on.
for (var i = 0; (node = dad.getElementsByTagName("td").item(i)); i++) {
if (node.firstChild.nodeValue == name) {
colInx = i;
sortCount[colInx] += 1;
} else {
// Clearing the sort count for column i as the data is no
// longer sorted by column i.
sortCount[i] = 0;
}
}
var tbody = dad.parentNode.parentNode.getElementsByTagName("tbody").item(0);
// For every row in the table...
for (var j = 0; (node = tbody.getElementsByTagName("tr").item(j)); j++) {
a[j] = new Array();
// The required sort text.
a[j][0] = getConcatenedTextContent(
node.getElementsByTagName("td").item(colInx));
alphaCharsInCol = (alphaCharsInCol || a[j][0].match(/[a-zA-Z]/));
// - sh>The following two lines were designed to sort the original
// table by surname (in column 2) and name (in column 1) after
// whatever column is chosen to sort in first.
// - We leave this design here for the future reference in case
// we ever need a second sort choice
// a[j][1] = getConcatenedTextContent(node.getElementsByTagName("td").item(1));
// a[j][2] = getConcatenedTextContent(node.getElementsByTagName("td").item(0));
a[j][3] = node;
}
a.sort(compare);
// - SH>The following code from the owner won't work if the first two
// rows in original display remain their previous positions after
// sorting. I.e. In such cases, the first time column head click
// always leads to a descending order sorting.
// - We introduce a sortCount array to solve this problem.
/*--------------------------------------------------------
// not a perfect way to check, but hell, it suits me fine
if (a[0][0] == getConcatenedTextContent(tbody.getElementsByTagName("tr").item(0).getElementsByTagName("td").item(i))
&& a[1][0] == getConcatenedTextContent(tbody.getElementsByTagName("tr").item(1).getElementsByTagName("td").item(i)))
a.reverse();
---------------------------------------------------------*/
// For consecutive clicks(sorting) under a specific column, the
// even number click leads to a descending order sorting.
if(sortCount[colInx]%2 == 0) a.reverse();
for (var j = 0; j < a.length; j++) {
// - Since each node is unique, appending the nodes will move them
// from their current location.
// - This has issues on Netscape 7 which has problem re-rendering
// the table. Since there's no easy to find workaround and
// Netscape 7 has less than 1% market share, we won't be fixing
// the issue at this time.
tbody.appendChild(a[j][3]);
}
}
function init(e) {
// Skip if the necessary level of DOM support isn't present.
if (!document.getElementsByTagName) return;
// Tables to be sorted must have class="sortable_table" in
// tag
var tbl;
for (var j=0; (tbl=document.body.getElementsByTagName("table").item(j));
j++) {
var namedItem = tbl.attributes.getNamedItem("class");
// - tbl.getAttribute("class") doesn't work on Internet
// Explorer. Thus, we have to use a different method to get
// the class attribute.
// - tbl.attributes.getNamedItem("class") always returns an object on
// Internet Explorer. On some other browsers (eg. Firefox)
// it returns null if the attribute is not found, so we have to check
// that the attribute exists before accessing the value.
if (namedItem && namedItem.value == "sortable_table") {
var thead = tbl.getElementsByTagName("thead").item(0);
var node;
for (var i = 0; (node =thead.getElementsByTagName("td").item(i)); i++) {
if (node.addEventListener) {
sortCount[i] = 0;
node.addEventListener("click",sort,false);
} else if (node.attachEvent) {
sortCount[i] = 0;
node.attachEvent("onclick",sort);
}
}
}
}
}
dy_attach_onload_event(init);
|