This article describes how JavaScript sorts tables or elements by text, numbers, or dates. Share to everyone for your reference. The implementation method is as follows:
Sorting table columns correctly by text, number or date. There are other//versions, plugins, etc., for this but they the either are restricted to specific//date formats, or requ IRE EVERY row-element to be given a sort attribute; Mine//can handle many different date and number formats, and even allows for specific//cells
The overall date/number format for that column. My version also enables sorting of element Hierarchies:such as a DIV containing//p-paragraphs and Spans-this Coul D even be a image-gallery containing prices//or dates within.
Very Efficient as well!! example:andrew.dx.am/sortgallerydel.html//Addsorttotables (); 'll make the table headers clickable, to sort columns in//ascending or descending order, for all tables with class= ' so
Rtit ". SortTable (TBL, col); Would sort the table (TBL is a ID or Table object) by//The supplied column index (indexed from 0) in ascending or desce
Nding order. Addsortbydate (TBL, col, Datemask);
Enables sorting of a column by date,///specified by a date-mask such as ' Dd-mmm-yy '. Addsortbynumber (TBL, col); Enables sorting of a column by number. This assumes A//period. As the decimal separator (if present);
It ignores any other non-numeric//characters. Sortelements (Parentel, Childtag, Coltag, Colindex); would sort (non-table)//elements in ascending or descending order. For example, an UL containing LIs//and spans. COLINDEX specifies which span to sort;
There may is more than one in//the LI (0 indexed).
Example:sortelements (' divID ', ' p ', ' span ', 2);
3rd span within each paragraph. AddSortByDate2 (Parentel, Childtag, Coltag, Colindex, Datemask); and//AddSortByNumber2 (Parentel, Childtag, Coltag, Colindex)//provide the same feature-set as Addsortbydate and Addsor
Tbynumber does//for tables, but for element hierarchies. If There are dates or numbers in a column (or element) which don ' t meet the//Date-mask or number foRmatting necessary to sort correctly, then this individual//elements can be given the attribute "sort" and they'll s
Till sort correctly! For example, with a date column <td sort= "2012/12/20" > would still sort A//cell correctly.
This format ' YYYY/MM/DD ' is converted into a Date () object.) var monthnames = ["January", "February", "March", "April", "may", "June", "July", "August", "September", "October", "No
Vember "," December "];
var daynames = ["Sunday", "Monday", "Tueday", "Wednesday", "Thursday", "Friday", "Saturday"];
var shortmths = ["No More", "Feb", "Mar", "APR", "may", "June", "O", "Aug", "Sep", "Oct", "Nov", "Dec"];
var shortdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var addevent = function (Elem, EventType, func) {//Helper function. if (elem.addeventlistener) addevent = function (Elem, EventType, func) {Elem.addeventlistener (EventType, func
, false);
}; else if (elem.attachevent) addevent = function (elem, EventType, func) {elem.attachevent (' on ' + EventType, func);
};
else addevent = function (Elem, EventType, func) {elem[' on ' + eventtype] = func;
};
Addevent (Elem, EventType, func);
}; Sort methods/algorithms Attributed:var sorttable = function (tbl, col) {//could to be called directly sortelements (
TBL, ' tr ', ' TD ', COL);
};
var sortelements = function (Parentel, Childtag, Coltag, Colindex) {//Example use:sortelements (' table1 ', ' tr ', ' TD ', 2) or sortelements (' List1 ', ' li ')//or sortelements (' divname ', ' p ', ' span ', 3) var i, J, cTags = {}, startAt = 0, child
Len, Achild, Elem, sortby, content, Elems = [], Sortedlen, Frag, Hdrslen, HDR;
var parent = (typeof Parentel = = ' string ')?
document.getElementById (Parentel): Parentel; var asctext = function (A, B) {//Sort () by. data as text var x = a.data, y = b.data, Xnum = parsefloat (x), Ynu
m = parsefloat (y);
Check if each begin with a number ... if (!isnan (xnum) &&!isnan (ynum) && (xnum-ynum)) return xnum-ynum;
Return ((x < y)?-1: ((x > Y)? 1:0));
}; var desctext = function (A, B) {//Sort () by. data var x = a.data, y = b.data, Xnum = parsefloat (x), ynum = par
Sefloat (y);
Check if each begin with a number ...
if (!isnan (xnum) &&!isnan (ynum) && (ynum-xnum)) return ynum-xnum;
Return ((x > Y)?-1: ((x < y)? 1:0));
};
var ascnum = function (A, B) {//used with dates as OK return a.data-b.data;
};
var descnum = function (A, b) {return b.data-a.data;
}; if (parent.nodeName.toLowerCase () = = ' table ') {if (Childtag = = ' tr ') {sortby = Parent.rows[0].cells[colindex ].sortby | |
' Text '; Parent = Parent.tbodies[0] | |
Parent
if (parent.rows[0].cells[0].nodename.tolowercase () = = ' th ') {startAt = 1;
} cTags = Parent.getelementsbytagname (Childtag); if (typeof Colindex = = ' undEfined ') {sortby = ' text ';//Sort simple lists or paragraphs as text} for (i = startAt, Childlen = Ctags.lengt H i < Childlen; i++) {///..
Go forward examining each child achild = ctags[i]; Elem = (coltag)?
Achild.getelementsbytagname (Coltag) [Colindex]: achild;
if (elem) {if (!sortby) {//Sorting non-table Columns ... SortBy = (typeof elem.numbervalue!= ' undefined ')? ' Number ': ((typeof elem.datevalue!= ' undefined ')?
' Date ': ' Text ');
Switch (sortby) {//Can supply ' sort ' attributes to enable sorting of numbers, etc.
For example, <td sort= ' 2011/02/12 ' > for a date.
Case ' text ': content = (Elem.getattribute (' sort ') | |
Elem.firstChild.nodeValue). toLowerCase ();
Break
Case ' number ': content = Elem.numbervalue;
Break
Case ' Date ': content = Elem.datevalue;
Break Default:conTent = (Elem.getattribute (' sort ') | |
Elem.firstChild.nodeValue). toLowerCase ();
Break
} j = Elems.length;
if (!achild.id) achild.id = ' Tempsortid ' + j;
Elems[j] = {data:content, tempID:aChild.id}; }//The following'll determine if the TABLE/ETC has already been//by the sorted column or tag. If So, it would sort in ascending or descending//order.
It creates custom element properties to the parent element to//Remember the previous sort details.
if (typeof Colindex = = ' undefined ') colindex = 0;
if (parent.prevtag && Parent.prevtag = = (typeof Coltag = = ' undefined ')? Childtag:coltag)) {if (Parent.prevcol = = Colindex) {//sorting by the same column as previously Paren T.prevsort = (Parent.prevsort = = ' ASC ')?
' desc ': ' ASC ';
else {//sorting by no other column Parent.prevcol = Colindex;
Parent.prevsort = ' ASC '; }} else {//sOrting for the "1st time" or by a different tag Parent.prevtag = ((typeof Coltag = = ' undefined ')? childtag:coltag);
Parent.prevcol = Colindex;
Parent.prevsort = ' ASC ';
} if (Parent.prevsort = = ' desc ') {//' desc ' is the previous sort order ...
Switch (sortby) {case ' text ': Elems.sort (Desctext); Case ' number ': Elems.sort (Descnum);
Break Case ' Date ': Elems.sort (Descnum);
Break Default:elems.sort (Desctext);
Break
} else {switch (sortby) {case ' text ': Elems.sort (Asctext); Case ' number ': Elems.sort (Ascnum);
Break Case ' Date ': Elems.sort (Ascnum);
Break Default:elems.sort (Asctext);
Break
} Frag = Document.createdocumentfragment ();
for (i = 0, Sortedlen = elems.length i < Sortedlen; i++) {elem = document.getElementById (elems[i].tempid);
Frag.appendchild (Elem);
if ((elem.id). substr (0,10) = = ' Tempsortid ') elem.removeattribute (' id '); } Parent. appendchild (Frag);
Elems = null; return parent.prevsort;
not currently used}; var addsorttotables = function () {//.. If table has Class-name ' sortit ' var tables = document.getelementsbytagname (' table '), I, J, Tbllen, TBL, HDRs, HDRs
Len;
function Preservesortscope (a,b,c,d) {return function () {//Assign-sortelements fn. to a table header
Sortelements (A, B, C, D); }//Add sorting to table headers for (i = 0, Tbllen = tables.length i < Tbllen; i++) {tbl = Tables[i]
;
if (tbl.className.indexOf (' sortit ') + 1) {HDRs = tbl.getelementsbytagname (' th '); if (HDRs) {for (j = 0, Hdrslen = hdrs.length J < Hdrslen; J + +) {addevent (hdrs[j), ' click ', Prese
Rvesortscope (TBL, ' tr ', ' TD ', j));
If there ' s no title already, add "click to sort" if (!hdrs[j].title) hdrs[j].setattribute (' title ',
' Click to sort ');
}
}
}
}
}; var addsortbydate = functIon (TBL, col, datemask) {//Input:the table name (or object), a column index (or array)//and a date mask (' dd-mm
M-yy ')//Adds a sortby = ' Date ' property to the ' the ' the ' the ' the ' the ', ' ignore the ' a header row
var i, Rlen, cell;
while (col.length) addsortbydate (Tbl,col.pop (), datemask);
if ((col instanceof Array) | | | isNaN (COL)) return; var tbl = (typeof tbl = = ' string ')?
document.getElementById (TBL): TBL;
Tbl.rows[0].cells[col].sortby = ' Date ';
AddSortByDate2 (TBL, ' tr ', ' TD ', Col, Datemask);
};
var AddSortByDate2 = function (Parentel, Childtag, Coltag, Colindex, datemask) {var kids, startAt = 0, I, Rlen, cell;
var parent = (typeof Parentel = = ' string ')?
document.getElementById (Parentel): Parentel;
if (parent.nodeName.toLowerCase () = = ' table ') {parent = Parent.tbodies[0] | |
StartAt = (parent.rows[0].cells[0].nodename.tolowercase () = = ' th ') * 1;
} kids = Parent.getelementsbytagname (Childtag); for ( i = startAt, Rlen = kids.length; i < Rlen;
i++) {cell = Kids[i].getelementsbytagname (Coltag) [Colindex];
if (cell) {if (typeof cell.numbervalue!= ' undefined ') delete cell.numbervalue; The above enables switching from a # to a date sort//(although v. unlikely) if (Cell.getattribute ('
Sort ')) {//Use sort attribute if present Cell.datevalue = new Date (Cell.getattribute (' sort '));
else {cell.datevalue = new Date (Stringtodate (Cell.firstChild.nodeValue, datemask)); } if (cell.dateValue.toString () = = "NaN" | | cell.dateValue.toString () = "Invalid Date") {CELL.D
Atevalue = 0;
}
}
}
}; var addsortbynumber = function (tbl, col) {//COL is a column index or array of indices//would ignore the
Assuming it is a header row var i, Rlen, cell, tempnum;
while (col.length) Addsortbynumber (Tbl,col.pop ()); if ((col instanceof Array) | | isNaN (COL) return; TBL = (typeof tbl = = ' string ')?
document.getElementById (TBL): TBL;
Tbl.rows[0].cells[col].sortby = ' number ';
AddSortByNumber2 (TBL, ' tr ', ' TD ', COL);
};
var AddSortByNumber2 = function (Parentel, Childtag, Coltag, Colindex) {var kids, startAt = 0, I, Rlen, cell, tempnum;
var parent = (typeof Parentel = = ' string ')?
document.getElementById (Parentel): Parentel;
if (parent.nodeName.toLowerCase () = = ' table ') {parent = Parent.tbodies[0] | |
StartAt = (parent.rows[0].cells[0].nodename.tolowercase () = = ' th ') * 1;
} kids = Parent.getelementsbytagname (Childtag);
for (i = startAt, Rlen = Kids.length i < Rlen; i++) {cell = Kids[i].getelementsbytagname (Coltag) [Colindex];
if (cell) {if (typeof cell.datevalue!= ' undefined ') delete cell.datevalue; The above enables switching from a date to a number sort//(although v. unlikely) Tempnum = Cell.getattrib Ute (' sort ') | |
Cell.firstChild.nodeValue; TempNum = Tempnum.replace (/[^0-9.-]/g, "");
Cell.numbervalue = parsefloat (tempnum);
if (isNaN (cell.numbervalue)) Cell.numbervalue = 0.0;
}
}
}; var stringtodate = function (Sdate, Sformat, cutOff) {//Input:a date value as a string, it ' s format as a string e.g.
' Dd-mmm-yy '//optional:a cutoff (integer) for 2 digit years.
If no ' d ' appears in the format string then the 1st of the month is assumed. If the cut-off is then the value would be converted//to 2020;
If the then this would be converted to 1940.
If no cut-off is supplied then ' would be pre-pended to the year (YY). Output:a string in the format ' yyyy/mm/dd ' or '/won't be attempt to convert certain combinations e.g. DMM, MDD,
DDM, Yyyyd.
var sparsed, Fndsingle;
Sparsed would be constructed in the format ' yyyy/mm/dd ' sdate = sdate.tostring (). toUpperCase ();
Sformat = Sformat.touppercase (); if (Sformat.search (/mmmm| mmm/) + 1) { Replace Mar/march with, etc. Sdate = Sdate.replace (new RegExp (' + shortmths.join (' | ') + ') [a-z]* ', ' gi '), function (m) {var i = shortmth
S.indexof (M.charat (0). toUpperCase () + M.SUBSTR (1, 2). toLowerCase ()) + 1; Return ((I < 10)?
"0" + I: "" + i). toString ();
}); Sformat = Sformat.replace (/mmmm|
mmm/g, ' MM '); } if (Sformat.search (/dddd| ddd/) + 1) {//replace Tue/tuesday, etc. with ' Sdate = Sdate.replace (new RegExp (' + shortdays.join (' | ') + ') [A-z]
* ', ' gi '); Sformat = Sformat.replace (/dddd|
Ddd/g, ""); } sdate = Sdate.replace (^|\d) (\d) (? =\d|$)/g, function ($, $, $) {//single digits 2 with return $ + ' 0 '
+ $;
}); Sformat = Sformat.replace (/(^|[ ^dmy]) (d|
M) (=[^dmy]|$)/g, function ($, $) {return $ + $ + $//replace D or M with DD and MM});
Are there still single Ds or Ms? Fndsingle = Sformat.search (/(^|[ ^D]) D ([^d]|$) | (^| [^m])
M ([^m]|$)/) +1; if (Fndsingle) return "; // Don't attempt to parse, for example, ' DMM ' Sformat = Sformat.replace (/(^|[
^y]) (YY) (? =[^y]|$)/g, function ($, $, $, index) {var tempdate = sdate.substr (0, index + 1); Tempdate + = (cutOff)?
((parseint (SDATE.SUBSTR (index + 1, 2), ten) > CutOff)?
' 19 ': ' 20 '): ' 20 ';
Tempdate + = SDATE.SUBSTR (index + 1);
Sdate = tempdate;
Return $ + $ + $;
}); sparsed = (' Yyyy/mm/dd '). Replace (/yyyy| mm|
dd/g, function (m) {return (Sformat.indexof (m) + 1)?
Sdate.substr (Sformat.indexof (M), m.length): ';
}); if (Sparsed.charat (0) = = '/') {//If no specified, assume the current year sparsed = (new Date (). getFullYear
()) + sparsed;
} if (Sparsed.charat (sparsed.length-1) = = '/') {//If no date, assume the 1st of the month sparsed = ' 01 ';
}//should end up with characters. return (Sparsed.length = 10)?
sparsed: ';
};
wants this article to help you with your JavaScript programming.