19d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* 29d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee SortTable 39d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee version 2 49d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 7th April 2007 59d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ 69d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 79d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Instructions: 89d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Download this file 99d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Add <script src="sorttable.js"></script> to your HTML 109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Add class="sortable" to any table you'd like to make sortable 119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Click on the headers to sort 129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Thanks to many, many people for contributions and suggestions. 149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Licenced as X11: http://www.kryogenix.org/code/browser/licence.html 159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee This basically means: do what you want with it. 169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee*/ 179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 189d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 199d2d6e14b0932b6a74e01f393d5efed61458941bBob Leevar stIsIE = /*@cc_on!@*/false; 209d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 219d2d6e14b0932b6a74e01f393d5efed61458941bBob Leesorttable = { 229d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee init: function() { 239d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // quit if this function has already been called 249d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (arguments.callee.done) return; 259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // flag this function so we don't do the same thing twice 269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee arguments.callee.done = true; 279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // kill the timer 289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (_timer) clearInterval(_timer); 299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!document.createElement || !document.getElementsByTagName) return; 319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; 339d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee forEach(document.getElementsByTagName('table'), function(table) { 359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (table.className.search(/\bsortable\b/) != -1) { 369d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sorttable.makeSortable(table); 379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }); 399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee makeSortable: function(table) { 439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (table.getElementsByTagName('thead').length == 0) { 449d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // table doesn't have a tHead. Since it should have, create one and 459d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // put the first table row in it. 469d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee the = document.createElement('thead'); 479d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee the.appendChild(table.rows[0]); 489d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee table.insertBefore(the,table.firstChild); 499d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 509d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // Safari doesn't support table.tHead, sigh 519d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; 529d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 539d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (table.tHead.rows.length != 1) return; // can't cope with two header rows 549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 559d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as 569d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // "total" rows, for example). This is B&R, since what you're supposed 579d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // to do is put them in a tfoot. So, if there are sortbottom rows, 589d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // for backwards compatibility, move them to tfoot (creating it if needed). 599d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortbottomrows = []; 609d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i=0; i<table.rows.length; i++) { 619d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (table.rows[i].className.search(/\bsortbottom\b/) != -1) { 629d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortbottomrows[sortbottomrows.length] = table.rows[i]; 639d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 649d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 659d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (sortbottomrows) { 669d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (table.tFoot == null) { 679d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // table doesn't have a tfoot. Create one. 689d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee tfo = document.createElement('tfoot'); 699d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee table.appendChild(tfo); 709d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 719d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i=0; i<sortbottomrows.length; i++) { 729d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee tfo.appendChild(sortbottomrows[i]); 739d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 749d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee delete sortbottomrows; 759d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 769d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 779d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // work through each column and calculate its type 789d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee headrow = table.tHead.rows[0].cells; 799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i=0; i<headrow.length; i++) { 809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // manually override the type with a sorttable_type attribute 819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col 829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/); 839d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (mtch) { override = mtch[1]; } 849d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (mtch && typeof sorttable["sort_"+override] == 'function') { 859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee headrow[i].sorttable_sortfunction = sorttable["sort_"+override]; 869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else { 879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee headrow[i].sorttable_sortfunction = sorttable.guessType(table,i); 889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // make it clickable to sort 909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee headrow[i].sorttable_columnindex = i; 919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee headrow[i].sorttable_tbody = table.tBodies[0]; 929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee dean_addEvent(headrow[i],"click", function(e) { 939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 949d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (this.className.search(/\bsorttable_sorted\b/) != -1) { 959d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // if we're already sorted by this column, just 969d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // reverse the table, which is quicker 979d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sorttable.reverse(this.sorttable_tbody); 989d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.className = this.className.replace('sorttable_sorted', 999d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 'sorttable_sorted_reverse'); 1009d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.removeChild(document.getElementById('sorttable_sortfwdind')); 1019d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortrevind = document.createElement('span'); 1029d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortrevind.id = "sorttable_sortrevind"; 1039d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▴'; 1049d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.appendChild(sortrevind); 1059d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return; 1069d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1079d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { 1089d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // if we're already sorted by this column in reverse, just 1099d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // re-reverse the table, which is quicker 1109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sorttable.reverse(this.sorttable_tbody); 1119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.className = this.className.replace('sorttable_sorted_reverse', 1129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 'sorttable_sorted'); 1139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.removeChild(document.getElementById('sorttable_sortrevind')); 1149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind = document.createElement('span'); 1159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind.id = "sorttable_sortfwdind"; 1169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾'; 1179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.appendChild(sortfwdind); 1189d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return; 1199d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1209d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1219d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // remove sorttable_sorted classes 1229d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee theadrow = this.parentNode; 1239d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee forEach(theadrow.childNodes, function(cell) { 1249d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (cell.nodeType == 1) { // an element 1259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee cell.className = cell.className.replace('sorttable_sorted_reverse',''); 1269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee cell.className = cell.className.replace('sorttable_sorted',''); 1279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }); 1299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind = document.getElementById('sorttable_sortfwdind'); 1309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } 1319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortrevind = document.getElementById('sorttable_sortrevind'); 1329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } 1339d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.className += ' sorttable_sorted'; 1359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind = document.createElement('span'); 1369d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind.id = "sorttable_sortfwdind"; 1379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾'; 1389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.appendChild(sortfwdind); 1399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // build an array to sort. This is a Schwartzian transform thing, 1419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // i.e., we "decorate" each row with the actual sort key, 1429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // sort based on the sort keys, and then put the rows back in order 1439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // which is a lot faster because you only do getInnerText once per row 1449d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee row_array = []; 1459d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee col = this.sorttable_columnindex; 1469d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee rows = this.sorttable_tbody.rows; 1479d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var j=0; j<rows.length; j++) { 1489d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]]; 1499d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1509d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee /* If you want a stable sort, uncomment the following line */ 1519d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee //sorttable.shaker_sort(row_array, this.sorttable_sortfunction); 1529d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee /* and comment out this one */ 1539d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee row_array.sort(this.sorttable_sortfunction); 1549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1559d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee tb = this.sorttable_tbody; 1569d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var j=0; j<row_array.length; j++) { 1579d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee tb.appendChild(row_array[j][1]); 1589d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1599d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1609d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee delete row_array; 1619d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }); 1629d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1639d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1649d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 1659d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1669d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee guessType: function(table, column) { 1679d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // guess the type of a column based on its first non-blank row 1689d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfn = sorttable.sort_alpha; 1699d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i=0; i<table.tBodies[0].rows.length; i++) { 1709d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]); 1719d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (text != '') { 1729d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (text.match(/^-?[�$�]?[\d,.]+%?$/)) { 1739d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return sorttable.sort_numeric; 1749d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1759d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // check for a date: dd/mm/yyyy or dd/mm/yy 1769d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // can have / or . or - as separator 1779d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // can be mm/dd as well 1789d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee possdate = text.match(sorttable.DATE_RE) 1799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (possdate) { 1809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // looks like a date 1819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee first = parseInt(possdate[1]); 1829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee second = parseInt(possdate[2]); 1839d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (first > 12) { 1849d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // definitely dd/mm 1859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return sorttable.sort_ddmm; 1869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else if (second > 12) { 1879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return sorttable.sort_mmdd; 1889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else { 1899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // looks like a date, but we can't tell which, so assume 1909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // that it's dd/mm (English imperialism!) and keep looking 1919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sortfn = sorttable.sort_ddmm; 1929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1949d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1959d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1969d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return sortfn; 1979d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 1989d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1999d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee getInnerText: function(node) { 2009d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // gets the text we want to use for sorting for a cell. 2019d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // strips leading and trailing whitespace. 2029d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // this is *not* a generic getInnerText function; it's special to sorttable. 2039d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // for example, you can override the cell text with a customkey attribute. 2049d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // it also gets .value for <input> fields. 2059d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 2069d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee hasInputs = (typeof node.getElementsByTagName == 'function') && 2079d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee node.getElementsByTagName('input').length; 2089d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 2099d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (node.getAttribute("sorttable_customkey") != null) { 2109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return node.getAttribute("sorttable_customkey"); 2119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee else if (typeof node.textContent != 'undefined' && !hasInputs) { 2139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return node.textContent.replace(/^\s+|\s+$/g, ''); 2149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee else if (typeof node.innerText != 'undefined' && !hasInputs) { 2169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return node.innerText.replace(/^\s+|\s+$/g, ''); 2179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2189d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee else if (typeof node.text != 'undefined' && !hasInputs) { 2199d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return node.text.replace(/^\s+|\s+$/g, ''); 2209d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2219d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee else { 2229d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee switch (node.nodeType) { 2239d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee case 3: 2249d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (node.nodeName.toLowerCase() == 'input') { 2259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return node.value.replace(/^\s+|\s+$/g, ''); 2269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee case 4: 2289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return node.nodeValue.replace(/^\s+|\s+$/g, ''); 2299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee break; 2309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee case 1: 2319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee case 11: 2329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var innerText = ''; 2339d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i = 0; i < node.childNodes.length; i++) { 2349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee innerText += sorttable.getInnerText(node.childNodes[i]); 2359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2369d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return innerText.replace(/^\s+|\s+$/g, ''); 2379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee break; 2389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee default: 2399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return ''; 2409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 2439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 2449d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee reverse: function(tbody) { 2459d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // reverse the rows in a tbody 2469d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee newrows = []; 2479d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i=0; i<tbody.rows.length; i++) { 2489d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee newrows[newrows.length] = tbody.rows[i]; 2499d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2509d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i=newrows.length-1; i>=0; i--) { 2519d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee tbody.appendChild(newrows[i]); 2529d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2539d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee delete newrows; 2549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 2559d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 2569d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee /* sort functions 2579d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee each sort function takes two parameters, a and b 2589d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee you are comparing a[0] and b[0] */ 2599d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sort_numeric: function(a,b) { 2609d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); 2619d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (isNaN(aa)) aa = 0; 2629d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); 2639d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (isNaN(bb)) bb = 0; 2649d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return aa-bb; 2659d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 2669d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sort_alpha: function(a,b) { 2679d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (a[0]==b[0]) return 0; 2689d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (a[0]<b[0]) return -1; 2699d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return 1; 2709d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 2719d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sort_ddmm: function(a,b) { 2729d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee mtch = a[0].match(sorttable.DATE_RE); 2739d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee y = mtch[3]; m = mtch[2]; d = mtch[1]; 2749d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (m.length == 1) m = '0'+m; 2759d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (d.length == 1) d = '0'+d; 2769d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee dt1 = y+m+d; 2779d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee mtch = b[0].match(sorttable.DATE_RE); 2789d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee y = mtch[3]; m = mtch[2]; d = mtch[1]; 2799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (m.length == 1) m = '0'+m; 2809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (d.length == 1) d = '0'+d; 2819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee dt2 = y+m+d; 2829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (dt1==dt2) return 0; 2839d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (dt1<dt2) return -1; 2849d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return 1; 2859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 2869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sort_mmdd: function(a,b) { 2879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee mtch = a[0].match(sorttable.DATE_RE); 2889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee y = mtch[3]; d = mtch[2]; m = mtch[1]; 2899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (m.length == 1) m = '0'+m; 2909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (d.length == 1) d = '0'+d; 2919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee dt1 = y+m+d; 2929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee mtch = b[0].match(sorttable.DATE_RE); 2939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee y = mtch[3]; d = mtch[2]; m = mtch[1]; 2949d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (m.length == 1) m = '0'+m; 2959d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (d.length == 1) d = '0'+d; 2969d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee dt2 = y+m+d; 2979d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (dt1==dt2) return 0; 2989d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (dt1<dt2) return -1; 2999d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return 1; 3009d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 3019d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3029d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee shaker_sort: function(list, comp_func) { 3039d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // A stable sort function to allow multi-level sorting of data 3049d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // see: http://en.wikipedia.org/wiki/Cocktail_sort 3059d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // thanks to Joseph Nahmias 3069d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var b = 0; 3079d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var t = list.length - 1; 3089d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var swap = true; 3099d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee while(swap) { 3119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee swap = false; 3129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for(var i = b; i < t; ++i) { 3139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if ( comp_func(list[i], list[i+1]) > 0 ) { 3149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var q = list[i]; list[i] = list[i+1]; list[i+1] = q; 3159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee swap = true; 3169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } // for 3189d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee t--; 3199d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3209d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!swap) break; 3219d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3229d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for(var i = t; i > b; --i) { 3239d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if ( comp_func(list[i], list[i-1]) < 0 ) { 3249d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var q = list[i]; list[i] = list[i-1]; list[i-1] = q; 3259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee swap = true; 3269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } // for 3289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee b++; 3299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } // while(swap) 3319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee} 3339d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* ****************************************************************** 3359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Supporting functions: bundled here to avoid depending on a library 3369d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee ****************************************************************** */ 3379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// Dean Edwards/Matthias Miller/John Resig 3399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* for Mozilla/Opera9 */ 3419d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeif (document.addEventListener) { 3429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee document.addEventListener("DOMContentLoaded", sorttable.init, false); 3439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee} 3449d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3459d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* for Internet Explorer */ 3469d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/*@cc_on @*/ 3479d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/*@if (@_win32) 3489d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); 3499d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var script = document.getElementById("__ie_onload"); 3509d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee script.onreadystatechange = function() { 3519d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (this.readyState == "complete") { 3529d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sorttable.init(); // call the onload handler 3539d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }; 3559d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/*@end @*/ 3569d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3579d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* for Safari */ 3589d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeif (/WebKit/i.test(navigator.userAgent)) { // sniff 3599d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var _timer = setInterval(function() { 3609d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (/loaded|complete/.test(document.readyState)) { 3619d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee sorttable.init(); // call the onload handler 3629d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3639d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }, 10); 3649d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee} 3659d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3669d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* for other browsers */ 3679d2d6e14b0932b6a74e01f393d5efed61458941bBob Leewindow.onload = sorttable.init; 3689d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3699d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// written by Dean Edwards, 2005 3709d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// with input from Tino Zijdel, Matthias Miller, Diego Perini 3719d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3729d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// http://dean.edwards.name/weblog/2005/10/add-event/ 3739d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 3749d2d6e14b0932b6a74e01f393d5efed61458941bBob Leefunction dean_addEvent(element, type, handler) { 3759d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (element.addEventListener) { 3769d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee element.addEventListener(type, handler, false); 3779d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else { 3789d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // assign each event handler a unique ID 3799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++; 3809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // create a hash table of event types for the element 3819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!element.events) element.events = {}; 3829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // create a hash table of event handlers for each element/event pair 3839d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var handlers = element.events[type]; 3849d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!handlers) { 3859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee handlers = element.events[type] = {}; 3869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // store the existing event handler (if there is one) 3879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (element["on" + type]) { 3889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee handlers[0] = element["on" + type]; 3899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // store the event handler in the hash table 3929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee handlers[handler.$$guid] = handler; 3939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // assign a global event handler to do all the work 3949d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee element["on" + type] = handleEvent; 3959d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 3969d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 3979d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// a counter used to create unique IDs 3989d2d6e14b0932b6a74e01f393d5efed61458941bBob Leedean_addEvent.guid = 1; 3999d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4009d2d6e14b0932b6a74e01f393d5efed61458941bBob Leefunction removeEvent(element, type, handler) { 4019d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (element.removeEventListener) { 4029d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee element.removeEventListener(type, handler, false); 4039d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else { 4049d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // delete the event handler from the hash table 4059d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (element.events && element.events[type]) { 4069d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee delete element.events[type][handler.$$guid]; 4079d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4089d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4099d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4119d2d6e14b0932b6a74e01f393d5efed61458941bBob Leefunction handleEvent(event) { 4129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var returnValue = true; 4139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // grab the event object (IE uses a global event object) 4149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); 4159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // get a reference to the hash table of event handlers 4169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var handlers = this.events[event.type]; 4179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // execute each event handler 4189d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i in handlers) { 4199d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.$$handleEvent = handlers[i]; 4209d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (this.$$handleEvent(event) === false) { 4219d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee returnValue = false; 4229d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4239d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4249d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return returnValue; 4259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4279d2d6e14b0932b6a74e01f393d5efed61458941bBob Leefunction fixEvent(event) { 4289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // add W3C standard event methods 4299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee event.preventDefault = fixEvent.preventDefault; 4309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee event.stopPropagation = fixEvent.stopPropagation; 4319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return event; 4329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4339d2d6e14b0932b6a74e01f393d5efed61458941bBob LeefixEvent.preventDefault = function() { 4349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.returnValue = false; 4359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4369d2d6e14b0932b6a74e01f393d5efed61458941bBob LeefixEvent.stopPropagation = function() { 4379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.cancelBubble = true; 4389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee} 4399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// Dean's forEach: http://dean.edwards.name/base/forEach.js 4419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* 4429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee forEach, version 1.0 4439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Copyright 2006, Dean Edwards 4449d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee License: http://www.opensource.org/licenses/mit-license.php 4459d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee*/ 4469d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4479d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// array-like enumeration 4489d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeif (!Array.forEach) { // mozilla already supports this 4499d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Array.forEach = function(array, block, context) { 4509d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var i = 0; i < array.length; i++) { 4519d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee block.call(context, array[i], i, array); 4529d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4539d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }; 4549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee} 4559d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4569d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// generic enumeration 4579d2d6e14b0932b6a74e01f393d5efed61458941bBob LeeFunction.prototype.forEach = function(object, block, context) { 4589d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (var key in object) { 4599d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (typeof this.prototype[key] == "undefined") { 4609d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee block.call(context, object[key], key, object); 4619d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4629d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4639d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4649d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4659d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// character enumeration 4669d2d6e14b0932b6a74e01f393d5efed61458941bBob LeeString.forEach = function(string, block, context) { 4679d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Array.forEach(string.split(""), function(chr, index) { 4689d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee block.call(context, chr, index, string); 4699d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee }); 4709d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4719d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 4729d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee// globally resolve forEach enumeration 4739d2d6e14b0932b6a74e01f393d5efed61458941bBob Leevar forEach = function(object, block, context) { 4749d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (object) { 4759d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee var resolve = Object; // default 4769d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (object instanceof Function) { 4779d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // functions have a "length" property 4789d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee resolve = Function; 4799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else if (object.forEach instanceof Function) { 4809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // the object implements a custom forEach method so use that 4819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee object.forEach(block, context); 4829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return; 4839d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else if (typeof object == "string") { 4849d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // the object is a string 4859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee resolve = String; 4869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else if (typeof object.length == "number") { 4879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // the object is array-like 4889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee resolve = Array; 4899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee resolve.forEach(object, block, context); 4919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 4929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee}; 4939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 494