/////////////////////////////////////////////////////////////////////////////////////////////////////// // // Generic Table sort. // // Basic Concept: // A table can be sorted by clicking on the title of any column in the table, toggling // between ascending and descending sorts. // // Assumptions: // The first row of the table contains column titles that are "clicked" to sort the table // // The images 'desc.gif','asc.gif','none.gif','sorting.gif' exist // // The img tag is in each column of the the title row to represent the sort graphic. // // The CSS classes 'alternateRow' and 'sortedColumn' exist so we can have alternating // colors for each row and a highlight the sorted column. Something like the // function sortTable(td_element,ignoreLastLines) { // If the optional ignoreLastLines parameter (number of lines *not* to sort at end of table) // was not passed then make it 0 ignoreLastLines = (typeof(ignoreLastLines)=='undefined') ? 0 : ignoreLastLines; var sortImages =['desc.gif','asc.gif','none.gif','sorting.gif']; // Get the image used in the first row of the current column var sortColImage = td_element.getElementsByTagName('img')[0]; // If current image is 'asc.gif' or 'none.gif' (elements 1 and 2 of sortImages array) then this will // be a descending sort else it will be ascending - get new sort image icon and set sort order flag var sortAscending = false; var newSortColImage = ""; if (sortColImage.getAttribute('src').indexOf(sortImages[1])>-1 || sortColImage.getAttribute('src').indexOf(sortImages[2])>-1) { newSortColImage = sortImages[0]; sortAscending = false; } else { newSortColImage = sortImages[1]; sortAscending = true; } // Assign "SORTING" image icon (element 3 of sortImages array)) to current column title // (will replace with newSortColImage when sort completes) sortColImage.setAttribute('src',sortImages[3]); // Find which column was clicked by getting it's column position var indexCol = td_element.cellIndex; // Get the table element from the td element that was passed as a parameter to this function var table_element = td_element.parentNode; while (table_element.nodeName != "TABLE") { table_element = table_element.parentNode; } // Get all "tr" elements from the table and assign then to the Array "tr_elements" var tr_elements = table_element.getElementsByTagName('tr'); // Get all the images used in the first row then set them to 'none.gif' // (element 2 or sortImages array) except for the current column (all ready been changed) var allImg = tr_elements[0].getElementsByTagName('img'); for(var i=0;i nextValue[0] ) return 1; } //----------------------------------------------------------------------------- // Functions to get and compare values during a sort. //----------------------------------------------------------------------------- // This code is necessary for browsers that don't reflect the DOM constants // (like IE). if (document.ELEMENT_NODE == null) { document.ELEMENT_NODE = 1; document.TEXT_NODE = 3; } function getTextValue(el) { var i; var s; // Find and concatenate the values of all text nodes contained within the // element. s = ""; for (i = 0; i < el.childNodes.length; i++) if (el.childNodes[i].nodeType == document.TEXT_NODE) s += el.childNodes[i].nodeValue; else if (el.childNodes[i].nodeType == document.ELEMENT_NODE && el.childNodes[i].tagName == "BR") s += " "; else // Use recursion to get text within sub-elements. s += getTextValue(el.childNodes[i]); return normalizeString(s); } // Regular expressions for normalizing white space. var whtSpEnds = new RegExp("^\\s*|\\s*$", "g"); var whtSpMult = new RegExp("\\s\\s+", "g"); function normalizeString(s) { s = s.replace(whtSpMult, " "); // Collapse any multiple whites space. s = s.replace(whtSpEnds, ""); // Remove leading or trailing white space. return s; } // Function used to modify values to make then sortable depending on the type of information function FormatForType(itm) { var sortValue = itm.toLowerCase(); // If the item matches a date pattern (MM/DD/YYYY or MM/DD/YY or M/DD/YYYY) if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/) || itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/) || itm.match(/^\d[\/-]\d\d[\/-]\d\d\d\d$/) ) { // Convert date to YYYYMMDD format for sort comparison purposes // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX var yr = -1; if (itm.length == 10) { sortValue = itm.substr(6,4)+itm.substr(0,2)+itm.substr(3,2); } else if (itm.length == 9) { sortValue = itm.substr(5,4)+"0" + itm.substr(0,1)+itm.substr(2,2); } else { yr = itm.substr(6,2); if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; } sortValue = yr+itm.substr(3,2)+itm.substr(0,2); } } // If the item matches a Percent patten (contains a percent sign) if (itm.match(/%/)) { // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string. sortValue = itm.replace(/[^0-9.-]/g,''); sortValue = parseFloat(sortValue); } // If item starts with a "(" and ends with a ")" then remove them and put a negative sign in front if (itm.substr(0,1) == "(" & itm.substr(itm.length - 1,1) == ")") { itm = "-" + itm.substr(1,itm.length - 2); } // If the item matches a currency pattern (starts with a dollar or negative dollar sign) if (itm.match(/^[£$]|(^-)/)) { // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string. sortValue = itm.replace(/[^0-9.-]/g,''); if (isNaN(sortValue)) { sortValue = 0; } else { sortValue = parseFloat(sortValue); } } // If the item matches a numeric pattern if (itm.match(/(\d*,\d*$)|(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/)) { // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string. sortValue = itm.replace(/[^0-9.-]/g,''); // sortValue = sortValue.replace(/,/g,''); if (isNaN(sortValue)) { sortValue = 0; } else { sortValue = parseFloat(sortValue); } } return sortValue; } //----------------------------------------------------------------------------- // Functions to update the table appearance after a sort. //----------------------------------------------------------------------------- // Style class names. var rowClsNm = "alternateRow"; var colClsNm = "sortedColumn"; // Regular expressions for setting class names. var rowTest = new RegExp(rowClsNm, "gi"); var colTest = new RegExp(colClsNm, "gi"); function makePretty(tblEl, col, ignoreLastLines) { var i, j; var rowEl, cellEl; // Set style classes on each row to alternate their appearance. for (i = 1; i < tblEl.rows.length - ignoreLastLines; i++) { rowEl = tblEl.rows[i]; rowEl.className = rowEl.className.replace(rowTest, ""); if (i % 2 != 0) rowEl.className += " " + rowClsNm; rowEl.className = normalizeString(rowEl.className); // Set style classes on each column (other than the name column) to // highlight the one that was sorted. for (j = 0; j < tblEl.rows[i].cells.length; j++) { cellEl = rowEl.cells[j]; cellEl.className = cellEl.className.replace(colTest, ""); if (j == col) cellEl.className += " " + colClsNm; cellEl.className = normalizeString(cellEl.className); } } } // // END Generic Table sort. /////////////////////////////////////////////////////////////////////////////////////////////////////// // For those browsers that fully support the CSS :hover pseudo class the "table.scrollTable tr:hover" definition above // will work fine, but Internet Explorer 6 only supports "hover" for "" tag elements, so we need to use the following // JavaScript to mimic support (at least until IE7 comes out, which does support "hover" for all elements) // Create a JavaScript function that dynamically assigns mouseover and mouseout events to all // rows in a table which is assigned the "scrollTable" class name, in order to simulate a "hover" // effect on each of the tables rows HoverRow = function() { // If an IE browser if (document.all) { var table_rows = 0; // Find the table that uses the "scrollTable" classname var allTableTags=document.getElementsByTagName("table"); for (i=0; i