0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 var stIsIE = false;
0020
0021 sorttable = {
0022 init: function() {
0023
0024 if (arguments.callee.done) return;
0025
0026 arguments.callee.done = true;
0027
0028 if (_timer) clearInterval(_timer);
0029
0030 if (!document.createElement || !document.getElementsByTagName) return;
0031
0032 sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
0033
0034 forEach(document.getElementsByTagName('table'), function(table) {
0035 if (table.className.search(/\bsortable\b/) != -1) {
0036 sorttable.makeSortable(table);
0037 }
0038 });
0039
0040 },
0041
0042 makeSortable: function(table) {
0043 if (table.getElementsByTagName('thead').length == 0) {
0044
0045
0046 the = document.createElement('thead');
0047 the.appendChild(table.rows[0]);
0048 table.insertBefore(the,table.firstChild);
0049 }
0050
0051 if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
0052
0053 if (table.tHead.rows.length != 1) return;
0054
0055
0056
0057
0058
0059 sortbottomrows = [];
0060 for (var i=0; i<table.rows.length; i++) {
0061 if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
0062 sortbottomrows[sortbottomrows.length] = table.rows[i];
0063 }
0064 }
0065 if (sortbottomrows) {
0066 if (table.tFoot == null) {
0067
0068 tfo = document.createElement('tfoot');
0069 table.appendChild(tfo);
0070 }
0071 for (var i=0; i<sortbottomrows.length; i++) {
0072 tfo.appendChild(sortbottomrows[i]);
0073 }
0074 delete sortbottomrows;
0075 }
0076
0077
0078 headrow = table.tHead.rows[0].cells;
0079 for (var i=0; i<headrow.length; i++) {
0080
0081 if (!headrow[i].className.match(/\bsorttable_nosort\b/)) {
0082 mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
0083 if (mtch) { override = mtch[1]; }
0084 if (mtch && typeof sorttable["sort_"+override] == 'function') {
0085 headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
0086 } else {
0087 headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
0088 }
0089
0090 headrow[i].sorttable_columnindex = i;
0091 headrow[i].sorttable_tbody = table.tBodies[0];
0092 dean_addEvent(headrow[i],"click", sorttable.innerSortFunction = function(e) {
0093
0094 if (this.className.search(/\bsorttable_sorted\b/) != -1) {
0095
0096
0097 sorttable.reverse(this.sorttable_tbody);
0098 this.className = this.className.replace('sorttable_sorted',
0099 'sorttable_sorted_reverse');
0100 rowlists = this.parentNode.getElementsByTagName("span");
0101 for (var j=0; j < rowlists.length; j++) {
0102 if (rowlists[j].className.search(/\bsorttable_sortfwdind\b/)) {
0103 rowlists[j].parentNode.removeChild(rowlists[j]);
0104 }
0105 }
0106 sortrevind = document.createElement('span');
0107 sortrevind.class = "sorttable_sortrevind";
0108 sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▾';
0109 this.appendChild(sortrevind);
0110 return;
0111 }
0112 if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
0113
0114
0115 sorttable.reverse(this.sorttable_tbody);
0116 this.className = this.className.replace('sorttable_sorted_reverse',
0117 'sorttable_sorted');
0118 rowlists = this.parentNode.getElementsByTagName("span");
0119 for (var j=0; j < rowlists.length; j++) {
0120 if (rowlists[j].className.search(/\sorttable_sortrevind\b/)) {
0121 rowlists[j].parentNode.removeChild(rowlists[j]);
0122 }
0123 }
0124 sortfwdind = document.createElement('span');
0125 sortfwdind.class = "sorttable_sortfwdind";
0126 sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▴';
0127 this.appendChild(sortfwdind);
0128 return;
0129 }
0130
0131
0132 theadrow = this.parentNode;
0133 forEach(theadrow.childNodes, function(cell) {
0134 if (cell.nodeType == 1) {
0135 cell.className = cell.className.replace('sorttable_sorted_reverse','');
0136 cell.className = cell.className.replace('sorttable_sorted','');
0137 }
0138 });
0139 rowlists = this.parentNode.getElementsByTagName("span");
0140 for (var j=0; j < rowlists.length; j++) {
0141 if (rowlists[j].className.search(/\bsorttable_sortfwdind\b/)
0142 || rowlists[j].className.search(/\sorttable_sortrevind\b/) ) {
0143 rowlists[j].parentNode.removeChild(rowlists[j]);
0144 }
0145 }
0146
0147 this.className += ' sorttable_sorted';
0148 sortfwdind = document.createElement('span');
0149 sortfwdind.class = "sorttable_sortfwdind";
0150 sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▴';
0151 this.appendChild(sortfwdind);
0152
0153
0154
0155
0156
0157 row_array = [];
0158 col = this.sorttable_columnindex;
0159 rows = this.sorttable_tbody.rows;
0160 for (var j=0; j<rows.length; j++) {
0161 row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
0162 }
0163
0164
0165
0166 row_array.sort(this.sorttable_sortfunction);
0167
0168 tb = this.sorttable_tbody;
0169 for (var j=0; j<row_array.length; j++) {
0170 tb.appendChild(row_array[j][1]);
0171 }
0172
0173 delete row_array;
0174 });
0175 }
0176 }
0177 },
0178
0179 guessType: function(table, column) {
0180
0181 sortfn = sorttable.sort_alpha;
0182 for (var i=0; i<table.tBodies[0].rows.length; i++) {
0183 text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
0184 if (text != '') {
0185 if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
0186 return sorttable.sort_numeric;
0187 }
0188
0189
0190
0191 possdate = text.match(sorttable.DATE_RE)
0192 if (possdate) {
0193
0194 first = parseInt(possdate[1]);
0195 second = parseInt(possdate[2]);
0196 if (first > 12) {
0197
0198 return sorttable.sort_ddmm;
0199 } else if (second > 12) {
0200 return sorttable.sort_mmdd;
0201 } else {
0202
0203
0204 sortfn = sorttable.sort_ddmm;
0205 }
0206 }
0207 }
0208 }
0209 return sortfn;
0210 },
0211
0212 getInnerText: function(node) {
0213
0214
0215
0216
0217
0218
0219 if (!node) return "";
0220
0221 hasInputs = (typeof node.getElementsByTagName == 'function') &&
0222 node.getElementsByTagName('input').length;
0223
0224 if (node.nodeType == 1 && node.getAttribute("sorttable_customkey") != null) {
0225 return node.getAttribute("sorttable_customkey");
0226 }
0227 else if (typeof node.textContent != 'undefined' && !hasInputs) {
0228 return node.textContent.replace(/^\s+|\s+$/g, '');
0229 }
0230 else if (typeof node.innerText != 'undefined' && !hasInputs) {
0231 return node.innerText.replace(/^\s+|\s+$/g, '');
0232 }
0233 else if (typeof node.text != 'undefined' && !hasInputs) {
0234 return node.text.replace(/^\s+|\s+$/g, '');
0235 }
0236 else {
0237 switch (node.nodeType) {
0238 case 3:
0239 if (node.nodeName.toLowerCase() == 'input') {
0240 return node.value.replace(/^\s+|\s+$/g, '');
0241 }
0242 case 4:
0243 return node.nodeValue.replace(/^\s+|\s+$/g, '');
0244 break;
0245 case 1:
0246 case 11:
0247 var innerText = '';
0248 for (var i = 0; i < node.childNodes.length; i++) {
0249 innerText += sorttable.getInnerText(node.childNodes[i]);
0250 }
0251 return innerText.replace(/^\s+|\s+$/g, '');
0252 break;
0253 default:
0254 return '';
0255 }
0256 }
0257 },
0258
0259 reverse: function(tbody) {
0260
0261 newrows = [];
0262 for (var i=0; i<tbody.rows.length; i++) {
0263 newrows[newrows.length] = tbody.rows[i];
0264 }
0265 for (var i=newrows.length-1; i>=0; i--) {
0266 tbody.appendChild(newrows[i]);
0267 }
0268 delete newrows;
0269 },
0270
0271
0272
0273
0274 sort_numeric: function(a,b) {
0275 aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
0276 if (isNaN(aa)) aa = 0;
0277 bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
0278 if (isNaN(bb)) bb = 0;
0279 return aa-bb;
0280 },
0281 sort_alpha: function(a,b) {
0282 if (a[0].toLowerCase()==b[0].toLowerCase()) return 0;
0283 if (a[0].toLowerCase()<b[0].toLowerCase()) return -1;
0284 return 1;
0285 },
0286 sort_ddmm: function(a,b) {
0287 mtch = a[0].match(sorttable.DATE_RE);
0288 y = mtch[3]; m = mtch[2]; d = mtch[1];
0289 if (m.length == 1) m = '0'+m;
0290 if (d.length == 1) d = '0'+d;
0291 dt1 = y+m+d;
0292 mtch = b[0].match(sorttable.DATE_RE);
0293 y = mtch[3]; m = mtch[2]; d = mtch[1];
0294 if (m.length == 1) m = '0'+m;
0295 if (d.length == 1) d = '0'+d;
0296 dt2 = y+m+d;
0297 if (dt1==dt2) return 0;
0298 if (dt1<dt2) return -1;
0299 return 1;
0300 },
0301 sort_mmdd: function(a,b) {
0302 mtch = a[0].match(sorttable.DATE_RE);
0303 y = mtch[3]; d = mtch[2]; m = mtch[1];
0304 if (m.length == 1) m = '0'+m;
0305 if (d.length == 1) d = '0'+d;
0306 dt1 = y+m+d;
0307 mtch = b[0].match(sorttable.DATE_RE);
0308 y = mtch[3]; d = mtch[2]; m = mtch[1];
0309 if (m.length == 1) m = '0'+m;
0310 if (d.length == 1) d = '0'+d;
0311 dt2 = y+m+d;
0312 if (dt1==dt2) return 0;
0313 if (dt1<dt2) return -1;
0314 return 1;
0315 },
0316
0317 shaker_sort: function(list, comp_func) {
0318
0319
0320
0321 var b = 0;
0322 var t = list.length - 1;
0323 var swap = true;
0324
0325 while(swap) {
0326 swap = false;
0327 for(var i = b; i < t; ++i) {
0328 if ( comp_func(list[i], list[i+1]) > 0 ) {
0329 var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
0330 swap = true;
0331 }
0332 }
0333 t--;
0334
0335 if (!swap) break;
0336
0337 for(var i = t; i > b; --i) {
0338 if ( comp_func(list[i], list[i-1]) < 0 ) {
0339 var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
0340 swap = true;
0341 }
0342 }
0343 b++;
0344 }
0345 }
0346 }
0347
0348
0349
0350
0351
0352
0353
0354
0355 if (document.addEventListener) {
0356 document.addEventListener("DOMContentLoaded", sorttable.init, false);
0357 }
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 if (/WebKit/i.test(navigator.userAgent)) {
0373 var _timer = setInterval(function() {
0374 if (/loaded|complete/.test(document.readyState)) {
0375 sorttable.init();
0376 }
0377 }, 10);
0378 }
0379
0380
0381 window.onload = sorttable.init;
0382
0383
0384
0385
0386
0387
0388 function dean_addEvent(element, type, handler) {
0389 if (element.addEventListener) {
0390 element.addEventListener(type, handler, false);
0391 } else {
0392
0393 if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
0394
0395 if (!element.events) element.events = {};
0396
0397 var handlers = element.events[type];
0398 if (!handlers) {
0399 handlers = element.events[type] = {};
0400
0401 if (element["on" + type]) {
0402 handlers[0] = element["on" + type];
0403 }
0404 }
0405
0406 handlers[handler.$$guid] = handler;
0407
0408 element["on" + type] = handleEvent;
0409 }
0410 };
0411
0412 dean_addEvent.guid = 1;
0413
0414 function removeEvent(element, type, handler) {
0415 if (element.removeEventListener) {
0416 element.removeEventListener(type, handler, false);
0417 } else {
0418
0419 if (element.events && element.events[type]) {
0420 delete element.events[type][handler.$$guid];
0421 }
0422 }
0423 };
0424
0425 function handleEvent(event) {
0426 var returnValue = true;
0427
0428 event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
0429
0430 var handlers = this.events[event.type];
0431
0432 for (var i in handlers) {
0433 this.$$handleEvent = handlers[i];
0434 if (this.$$handleEvent(event) === false) {
0435 returnValue = false;
0436 }
0437 }
0438 return returnValue;
0439 };
0440
0441 function fixEvent(event) {
0442
0443 event.preventDefault = fixEvent.preventDefault;
0444 event.stopPropagation = fixEvent.stopPropagation;
0445 return event;
0446 };
0447 fixEvent.preventDefault = function() {
0448 this.returnValue = false;
0449 };
0450 fixEvent.stopPropagation = function() {
0451 this.cancelBubble = true;
0452 }
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462 if (!Array.forEach) {
0463 Array.forEach = function(array, block, context) {
0464 for (var i = 0; i < array.length; i++) {
0465 block.call(context, array[i], i, array);
0466 }
0467 };
0468 }
0469
0470
0471 Function.prototype.forEach = function(object, block, context) {
0472 for (var key in object) {
0473 if (typeof this.prototype[key] == "undefined") {
0474 block.call(context, object[key], key, object);
0475 }
0476 }
0477 };
0478
0479
0480 String.forEach = function(string, block, context) {
0481 Array.forEach(string.split(""), function(chr, index) {
0482 block.call(context, chr, index, string);
0483 });
0484 };
0485
0486
0487 var forEach = function(object, block, context) {
0488 if (object) {
0489 var resolve = Object;
0490 if (object instanceof Function) {
0491
0492 resolve = Function;
0493 } else if (object.forEach instanceof Function) {
0494
0495 object.forEach(block, context);
0496 return;
0497 } else if (typeof object == "string") {
0498
0499 resolve = String;
0500 } else if (typeof object.length == "number") {
0501
0502 resolve = Array;
0503 }
0504 resolve.forEach(object, block, context);
0505 }
0506 };
0507