on any table to indicate that the table
redrawing after sorting should preserve cell style (override the global
preserve_style variable that you can set below). The other valid preserve_style
is "row", which is very useful if you use alternating colors for table rows.
Note that row style is slower than default, cell style is even slower due to
more update needed.
IE has a "design" (read:bug) that prevents setting innerHTML for rows ("design"
explained in http://msdn.microsoft.com/workshop/author/tables/buildtables.asp#TOM_Create,
bug documented for selects at http://support.microsoft.com/default.aspx?scid=kb;en-us;276228#appliesto).
Therefore for IE, "row" is actually equivalent with "cell" because it is implemented
the same way (blame IE for the speed!).
6. Use to indicate date format is DD/MM/YY or DD/MM/YYYY
Using | you can also indicate
it's european dates. | is
also european dates separated by '-' not '/'. Use the formatting you
could specify other date format, like Y-M-D. If Y is double digit, any number
smaller than 32 is deemed 20xx, otherwise it's 19xx. Note that D/M/Y (or any
user-specified format) could just part of the time string (the date part),
time conversion will be done correctly. Also note that if you choose custom
date format, due to the time consumed during date conversion, the sorting
would be much slower (2-3 times as slow).
The date/time formats accepted are:
1. Anything accepted directly by Javascript's Date.parse() function
(format best explained at "http://java.sun.com/j2se/1.3/docs/api/java/util/Date.html#parse(java.lang.String)");
2. Any combination of a date type specified by you and a time (hour, min,
seconds) format accepted by Date.parse(). Check the demo html page (http://www.mingyi.org/other/ts_demo.html) for
examples.
7. Remember that there are a number of parameters that you could customize
in the script!
8. Add 'ts_linkrow' to tag to indicate which header row the click-to-sort
links would be added to. Note that actually means that
the 2nd header row should be used as the click-to-sort row. By default, if
you do not add ts_linkrow to your tag, first table row would always
be used as the click-to-sort row.
9. Add 'ts_nosort' to the header row's tag to indicate this column
shouldn't be sorted. e.g. | abc | disable sorting link
on the column. You should also set use_ctrl_alt_click to false to disable
user using keyboard shortcut to get around the no sort rule on this column.
10.Add 'ts_forcesort' to the header row's tag to indicate this column
should be sorted only in one direction. e.g. | abc |
makes sure that the sorting on the column is always in ascending order. Use
"desc" for descending order.
*/
var ts_version = "1.26";
var ts_browser_agt = navigator.userAgent.toLowerCase();
var ts_browser_is_ie = ((ts_browser_agt.indexOf("msie") != -1) && (ts_browser_agt.indexOf("opera") == -1));
var ml_tsort = {
///////////////////////////////////////////////////
// configurable constants, modify as needed!
sort_col_title : "Click here to Sort!", // the popup text for the sorting link in the header columns
sort_col_asc_title : "Sorted in ascending order", // the popup text for the sorting link in the header column after the column's sorted in ascending order
sort_col_desc_title : "Sorted in descending order", // the popup text for the sorting link in the header column after the column's sorted in ascending order
sort_col_class : "abc", // whichever class you want the heading to be
sort_col_style : "text-decoration:none; font-weight:bold; color:black", // whichever style you want the link to look like
sort_col_class_post_sort : "def", // whichever class you want the heading for the column that's just sorted
sort_col_style_post_sort : "text-decoration:none; font-weight:bold; color:red", // whichever style you want the link to look like when the column for the link was sorted
sort_col_mouseover : "this.style.color='blue'", // what style the link should use onmouseover?
use_ctrl_alt_click : true, // allow ctrl-alt-click anywhere in table to activate sorting?
sort_only_sortable : true, // make all tables sortable by default or just make the tables with "sortable" class sortable?
//////////////////////////////////////////////////
// speed related constants, modify as needed!
table_content_might_change : false, // table content could be changed by other JS on-the-fly? if so, some speed improvements cannot be used.
preserve_style : "", // (row, cell) preserves style for row or cell e.g., row is useful when the table highlights rows alternatively. cell is much slower while no preservation's the fastest by far!
tell_me_time_consumption : false, // give stats about time consumed during sorting and table update/redrawing.
//////////////////////////////////////////////////////////
// anything below this line, modify at your own risk! ;)
smallest_int : -2147483648000, // date parse is in milliseconds, hence the 000
set_vars : function(event)
{
var e = (event)? event : window.event;
var element = (event)? ((event.target)? event.target : event.srcElement) : window.event.srcElement;
var clicked_td = ml_tsort.getParent(element,'TD') || ml_tsort.getParent(element,'TH');
var table = ml_tsort.getParent(element,'TABLE');
if(!table || table.rows.length < 1 || !clicked_td) return;
var column = clicked_td.cellIndex;
if (e.altKey && e.ctrlKey && ml_tsort.use_ctrl_alt_click) ml_tsort.resortTable(table.rows[0].cells[column]);
},
makeSortable: function(table)
{
if (table.rows && table.rows.length > 0) {
var rowidx = table.getAttribute("ts_linkrow") || 0;
var firstRow = table.rows[rowidx];
}
if (!firstRow) return;
var sortCell;
// We have a first row: assume it's the header (it works for too),
// and make its contents clickable links
for (var i=0;i'+txt+'';
}
if(sortCell) this.resortTable(sortCell);
},
sortables_init : function()
{
// Find all tables with class sortable and make them sortable
if (!document.getElementsByTagName) return;
var tbls = document.getElementsByTagName("table");
for (var ti=0;ti= column + 1) newRows[i++] = table.rows[j];
else if(t == 'thead') headcount++;
}
if(newRows.length == 0) return;
var time2 = new Date();
// check if we really need to sort
if(!td.getAttribute("ts_forcesort") && !this.table_content_might_change && table == this.last_sorted_table && column == lastSortCell)
newRows.reverse();
else
{
// Work out a type for the column
var sortfn, type = td.getAttribute("ts_type");
this.replace_pattern = '';
var itm, i;
for(i = 0; i < newRows.length; i++)
{
itm = this.getInnerText(newRows[i].cells[column]);
if(itm.match(/\S/)) break;
}
if(i == newRows.length) return;
itm = ml_trim(itm);
if(!type)
{
sortfn = this.sort_caseinsensitive;
if (this.match_date_format(newRows[i], 'M/D/Y')) sortfn = this.sort_date;
else if (itm.match(/^[¥£€$]/)) sortfn = this.sort_currency;
else if (itm.match(/^\d{1,3}(\.\d{1,3}){3}$/)) sortfn = this.sort_ip;
else if (itm.match(/^[+-]?\s*[0-9]+(?:\.[0-9]+)?(?:\s*[eE]\s*[+-]?\s*\d+)?$/))
sortfn = this.sort_numeric;
}
else if(type == 'date' && this.match_date_format(newRows[i], 'M/D/Y')) sortfn = this.sort_date;
else if(type == 'euro_date' && this.match_date_format(newRows[i], 'D/M/Y')) sortfn = this.sort_date;
else if(type == 'other_date' && this.match_date_format(newRows[i], td.getAttribute("ts_date_format"))) sortfn = this.sort_date;
else if(type == 'number') sortfn = this.sort_numeric;
else if(type == 'ip') sortfn = this.sort_ip;
else if(type == 'money') sortfn = this.sort_currency;
// else if(type == 'custom') sortfn = function(aa,bb) { a = this.getInnerText(aa.cells[this.sort_column_index]); b = this.getInnerText(bb.cells[this.sort_column_index]); eval(td.getAttribute("ts_sortfn")) }; // the coding here is shorter but interestingly it's also slower
else if(type == 'custom') { this.custom_code = td.getAttribute("ts_sortfn"); sortfn = this.custom_sortfn }
else { alert("unsupported sorting type or data not matching indicated type!"); return; }
table.setAttribute("ts_sortcell", column+1);
newRows.sort(sortfn);
if (lastSortDir == 'asc') newRows.reverse();
}
// set style of heading
var rowidx = table.getAttribute("ts_linkrow") || 0;
if(lastSortCell > -1 && table.rows[rowidx].cells[lastSortCell].firstChild.style)
{
table.rows[rowidx].cells[lastSortCell].firstChild.oldstyle = this.sort_col_style;
table.rows[rowidx].cells[lastSortCell].firstChild.style.cssText = this.sort_col_style;
table.rows[rowidx].cells[lastSortCell].firstChild.className = this.sort_col_class;
}
if(table.rows[rowidx].cells[column].firstChild.style)
{
table.rows[rowidx].cells[column].firstChild.oldstyle = this.sort_col_style_post_sort;
table.rows[rowidx].cells[column].firstChild.style.cssText = this.sort_col_style_post_sort;
table.rows[rowidx].cells[column].firstChild.className = this.sort_col_class_post_sort;
}
if (lastSortDir == 'desc') table.setAttribute('ts_sortdir','asc');
else table.setAttribute('ts_sortdir','desc');
// has to use tagName otherwise IE complains
if(lastSortCell > -1 && table.rows[rowidx].cells[lastSortCell].firstChild.tagName) table.rows[rowidx].cells[lastSortCell].firstChild.title = this.sort_col_title;
if(table.rows[rowidx].cells[column].firstChild.tagName) table.rows[rowidx].cells[column].firstChild.title = ((lastSortDir == 'desc')? this.sort_col_asc_title : this.sort_col_desc_title);
this.last_sorted_table = table;
var time3 = new Date();
var ps = table.getAttribute("preserve_style") || this.preserve_style;
if(ps == 'row' && !ts_browser_is_ie)
{
var tmp = new Array(newRows.length);
for (var i = 0; i < newRows.length; i++) tmp[i] = newRows[i].innerHTML;
for (var i = 0; i < newRows.length; i++) table.rows[i+headcount].innerHTML = tmp[i];
}
else if(ps == 'cell' || (ps == 'row' && ts_browser_is_ie))
{
var tmp = new Array(newRows.length);
for (var i = 0; i < newRows.length; i++)
for (var j = 0; j < newRows[i].cells.length; j++)
{
if(!tmp[i]) tmp[i] = new Array(newRows[i].cells.length);
tmp[i][j] = newRows[i].cells[j].innerHTML;
}
for (var i = 0; i < newRows.length; i++)
for (var j = 0; j < newRows[i].cells.length; j++)
table.rows[i+headcount].cells[j].innerHTML = tmp[i][j];
}
else
{
for (var i=0;i |