User:Franamax/sortable2.js

// Code adapted by Franamax from wikibits.js table sort functions // The wikibits.js code is based on code (c) 1997-2006 Stuart Langridge and Joost de Valk: // http://www.joostdevalk.nl/code/sortable-table/ // http://www.kryogenix.org/code/browser/sorttable/

function sortables_init { var idnum = 0; // Find all tables with class sortable and make them sortable // sortable2 begin var srch = "sortable"; for (x=0; x<2; ++x) { if (x==1) srch = "sortable2"; var tables = getElementsByClassName(document, "table", srch); // sortable2 end for (var ti = 0; ti < tables.length ; ti++) { if (!tables[ti].id) { tables[ti].setAttribute('id','sortable_table_id_'+idnum); ++idnum; } // sortable2 begin (x==0 ? ts_makeSortable(tables[ti]) : ts_makeSortable2(tables[ti])); } // sortable2 end } } function ts_makeSortable2(table) { var firstRow; /*	if (table.rows && table.rows.length > 0) { if (table.tHead && table.tHead.rows.length > 0) { firstRow = table.tHead.rows[table.tHead.rows.length-1]; } else { firstRow = table.rows[0]; }	}	if (!firstRow) return;

// We have a first row: assume it's the header, and make its contents clickable links for (var i = 0; i < firstRow.cells.length; i++) { var cell = firstRow.cells[i]; // sortable2 begin for (var x=0;x= 0) { // sortable2 end cell.innerHTML += '   '; }	} // sortable2 begin } //sortable2 end if (ts_alternate_row_colors) { ts_alternate(table); } }

function ts_resortTable(lnk) { // get the span var span = lnk.getElementsByTagName('span')[0];

var td = lnk.parentNode; var tr = td.parentNode; var column = td.cellIndex;

var table = tr.parentNode; while (table && !(table.tagName && table.tagName.toLowerCase == 'table')) table = table.parentNode; if (!table) return;

// Work out a type for the column if (table.rows.length <= 1) return;

// Skip the first row if that's where the headings are var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1); // sortable2 begin for (var i=0; i<table.rows.length; ++i) { if ((" "+table.rows[i].className+" ").indexOf(" sorthdg ") == -1) break; rowStart = i+1; } // find the column index in the actual table data // uncol is the number of columns rowspanned from higher up in the table // tgtrow is the rowspan adjusted row index of the clock target // tgtcol is the colspan adjusted column index of the click target // stop is a counter for when to stop examining columns in the previous rows // thisrow is an indexed row for span-counting, thiscell is an indexed cell // tgtspan is the rowspan of the cell in thisrow above the target // minspan is the smallest rowspan in thisrow, for the rare occasion when all the rowspans are >1 // x, y and rspan are work variables var uncol = 0; var stop = 0; var x = 0; var y = 0; var rspan = 0; var tgtspan = 0; var minspan = 0; var tgtrow = tr.rowIndex; var tgtcol = column; // find the "true" column index of the target within its own row for (x=0; x<column; ++x) { tgtcol += tr.cells[x].colSpan - 1; } // first pass - find the "real" target row by counting the rowspans of the cells above the target for (x=0; x= (tgtrow+1) ) continue; stop += thiscell.colSpan; if (stop >= tgtcol && tgtspan <= 0) tgtspn = rspan; } // increment the target row by the rowspan in the cell above it (minus the smallest span in the row) if (tgtspan > 0 && minspan != 999) { // sanity check, should always be true tgtrow += tgtspan - minspan; if (tgtrow < 1) tgtrow = 1; // this would be serious bad news if true if (tgtrow > 100) { tgtrow = 1; break; // this would be horrible news of breakage }     }   } // 2nd pass - now run down the rows above the target, find and count the cells with rowspans that will intrude onto the target row for (x=0;x= (tgtrow+1) ) { uncol += thiscell.colSpan; continue; }     stop += thiscell.colSspan; if (stop >= tgtcol) break; }  } // now set the "real" column in the actual table column = tgtcol + uncol; // sortable2 end var itm = ""; for (var i = rowStart; i < table.rows.length; i++) { if (table.rows[i].cells.length > column) { itm = ts_getInnerText(table.rows[i].cells[column]); itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, ""); if (itm != "") break; }	}	var sortfn = ts_sort_caseinsensitive; if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/)) sortfn = ts_sort_date; else if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/)) sortfn = ts_sort_date; else if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/)) sortfn = ts_sort_date; // pound dollar euro yen currency cents else if (itm.match(/(^[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/)) sortfn = ts_sort_currency; // We allow a trailing percent sign, which we just strip. This works fine // if percents and regular numbers aren't being mixed. else if (itm.match(/^[+-]?\d[\d,]*(\.[\d,]*)?([eE][+-]?\d[\d,]*)?\%?$/) ||	itm.match(/^[+-]?\.\d[\d,]*([eE][+-]?\d[\d,]*)?\%?$/) ||	itm.match(/^0x[\da-f]+$/i)) sortfn = ts_sort_numeric;

var reverse = (span.getAttribute("sortdir") == 'down');

var newRows = new Array; for (var j = rowStart; j < table.rows.length; j++) { var row = table.rows[j]; var keyText = ts_getInnerText(row.cells[column]); var oldIndex = (reverse ? -j : j);

newRows[newRows.length] = new Array(row, keyText, oldIndex); }

newRows.sort(sortfn);

var arrowHTML; if (reverse) { arrowHTML = ''; newRows.reverse; span.setAttribute('sortdir','up'); } else { arrowHTML = ''; span.setAttribute('sortdir','down'); }

// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones // don't do sortbottom rows for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1) table.tBodies[0].appendChild(newRows[i][0]); }	// do sortbottom rows only for (var i = 0; i < newRows.length; i++) { if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1) table.tBodies[0].appendChild(newRows[i][0]); }

// Delete any other arrows there may be showing var spans = getElementsByClassName(tr, "span", "sortarrow"); for (var i = 0; i < spans.length; i++) { spans[i].innerHTML = ''; }	span.innerHTML = arrowHTML;

if (ts_alternate_row_colors) { ts_alternate(table); } }