I have something like this
<table>
<thead>
<tr>
<th>S.L.</th>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Ronaldo</td>
</tr>
<tr>
<td>2</td>
<td>Messi</td>
</tr>
<tr>
<td>3</td>
<td>Ribery</td>
</tr>
<tr>
<td>4</td>
<td>Bale</td>
</tr>
</tbody>
</table>
What i want is to sort the <tr>
of <tbody>
when clicked th
in ascending and descending order alternatively in according to the following th
clicked.
S.L
th
then it shows the table rows in
descending and then ascending order alternatively at every click.Name
th
it should show the names in descending
order and then ascending order without change in their respective
S.L
here is fiddle
This question is related to
javascript
jquery
html
html-table
Offering an interactive sort handling multiple columns is nothing trivial.
Unless you want to write a good amount of code handling logic for multiple row clicks, editing and refreshing page content, managing sort algorithms for large tables… then you really are better off adopting a plug-in.
tablesorter, (with updates by Mottie) is my favorite. It’s easy to get going and very customizable. Just add the class tablesorter
to the table you want to sort, then invoke the tablesorter plugin in a document load event:
$(function(){
$("#myTable").tablesorter();
});
You can browse the documentation to learn about advanced features.
use Javascript sort() function
var $tbody = $('table tbody');
$tbody.find('tr').sort(function(a,b){
var tda = $(a).find('td:eq(1)').text(); // can replace 1 with the column you want to sort on
var tdb = $(b).find('td:eq(1)').text(); // this will sort on the second column
// if a < b return 1
return tda < tdb ? 1
// else if a > b return -1
: tda > tdb ? -1
// else they are equal - return 0
: 0;
}).appendTo($tbody);
If you want ascending you just have to reverse the > and <
Change the logic accordingly for you.
var TableIDvalue = "myTable";_x000D_
var TableLastSortedColumn = -1;_x000D_
_x000D_
function SortTable() {_x000D_
var sortColumn = parseInt(arguments[0]);_x000D_
var type = arguments.length > 1 ? arguments[1] : 'T';_x000D_
var dateformat = arguments.length > 2 ? arguments[2] : '';_x000D_
var table = document.getElementById(TableIDvalue);_x000D_
var tbody = table.getElementsByTagName("tbody")[0];_x000D_
var rows = tbody.getElementsByTagName("tr");_x000D_
_x000D_
var arrayOfRows = new Array();_x000D_
_x000D_
type = type.toUpperCase();_x000D_
_x000D_
dateformat = dateformat.toLowerCase();_x000D_
_x000D_
for (var i = 0, len = rows.length; i < len; i++) {_x000D_
arrayOfRows[i] = new Object;_x000D_
arrayOfRows[i].oldIndex = i;_x000D_
var celltext = rows[i].getElementsByTagName("td")[sortColumn].innerHTML.replace(/<[^>]*>/g, "");_x000D_
if (type == 'D') {_x000D_
arrayOfRows[i].value = GetDateSortingKey(dateformat, celltext);_x000D_
} else {_x000D_
var re = type == "N" ? /[^\.\-\+\d]/g : /[^a-zA-Z0-9]/g;_x000D_
arrayOfRows[i].value = celltext.replace(re, "").substr(0, 25).toLowerCase();_x000D_
}_x000D_
}_x000D_
_x000D_
if (sortColumn == TableLastSortedColumn) {_x000D_
arrayOfRows.reverse();_x000D_
} else {_x000D_
TableLastSortedColumn = sortColumn;_x000D_
switch (type) {_x000D_
case "N":_x000D_
arrayOfRows.sort(CompareRowOfNumbers);_x000D_
break;_x000D_
case "D":_x000D_
arrayOfRows.sort(CompareRowOfNumbers);_x000D_
break;_x000D_
default:_x000D_
arrayOfRows.sort(CompareRowOfText);_x000D_
}_x000D_
}_x000D_
var newTableBody = document.createElement("tbody");_x000D_
_x000D_
for (var i = 0, len = arrayOfRows.length; i < len; i++) {_x000D_
newTableBody.appendChild(rows[arrayOfRows[i].oldIndex].cloneNode(true));_x000D_
}_x000D_
table.replaceChild(newTableBody, tbody);_x000D_
}_x000D_
_x000D_
function CompareRowOfText(a, b) {_x000D_
var aval = a.value;_x000D_
var bval = b.value;_x000D_
return (aval == bval ? 0 : (aval > bval ? 1 : -1));_x000D_
}_x000D_
_x000D_
function deleteRow(i) {_x000D_
document.getElementById('myTable').deleteRow(i)_x000D_
}
_x000D_
<table id="myTable" border="1">_x000D_
<thead>_x000D_
<tr>_x000D_
<th>_x000D_
<input type="button" onclick="javascript: SortTable(0, 'T');" value="SORT" /></th>_x000D_
</tr>_x000D_
</thead>_x000D_
<tbody>_x000D_
<tr>_x000D_
<td>Shaa</td>_x000D_
<td>ABC</td>_x000D_
<td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>cnubha</td>_x000D_
<td>XYZ</td>_x000D_
<td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>Fine</td>_x000D_
<td>MNO</td>_x000D_
<td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>Amit</td>_x000D_
<td>PQR</td>_x000D_
<td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>Sultan</td>_x000D_
<td>FGH</td>_x000D_
<td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>Hello</td>_x000D_
<td>UST</td>_x000D_
<td><input type="button" value="Delete" onclick="deleteRow(this.parentNode.parentNode.rowIndex)" /></td>_x000D_
</tr>_x000D_
_x000D_
</tbody>_x000D_
</table>
_x000D_
I've been working on a function to work within a library for a client, and have been having a lot of trouble keeping the UI responsive during the sorts (even with only a few hundred results).
The function has to resort the entire table each AJAX pagination, as new data may require injection further up. This is what I had so far:
table
is the ID of the table being sorted.sort-attribute
, sort-direction
and the column attribute column
are all pre-set.Using some of the details above I managed to improve performance a bit.
function sorttable(table) {
var context = $('#' + table), tbody = $('#' + table + ' tbody'), sortfield = $(context).data('sort-attribute'), c, dir = $(context).data('sort-direction'), index = $(context).find('thead th[data-column="' + sortfield + '"]').index();
if (!sortfield) {
sortfield = $(context).data('id-attribute');
};
switch (dir) {
case "asc":
tbody.find('tr').sort(function (a, b) {
var sortvala = parseFloat($(a).find('td:eq(' + index + ')').text());
var sortvalb = parseFloat($(b).find('td:eq(' + index + ')').text());
// if a < b return 1
return sortvala < sortvalb ? 1
// else if a > b return -1
: sortvala > sortvalb ? -1
// else they are equal - return 0
: 0;
}).appendTo(tbody);
break;
case "desc":
default:
tbody.find('tr').sort(function (a, b) {
var sortvala = parseFloat($(a).find('td:eq(' + index + ')').text());
var sortvalb = parseFloat($(b).find('td:eq(' + index + ')').text());
// if a < b return 1
return sortvala > sortvalb ? 1
// else if a > b return -1
: sortvala < sortvalb ? -1
// else they are equal - return 0
: 0;
}).appendTo(tbody);
break;
}
In principle the code works perfectly, but it's painfully slow... are there any ways to improve performance?
You might want to see this page:
http://blog.niklasottosson.com/?p=1914
I guess you can go something like this:
DEMO:http://jsfiddle.net/g9eL6768/2/
HTML:
<table id="mytable"><thead>
<tr>
<th id="sl">S.L.</th>
<th id="nm">name</th>
</tr>
....
JS:
// sortTable(f,n)
// f : 1 ascending order, -1 descending order
// n : n-th child(<td>) of <tr>
function sortTable(f,n){
var rows = $('#mytable tbody tr').get();
rows.sort(function(a, b) {
var A = getVal(a);
var B = getVal(b);
if(A < B) {
return -1*f;
}
if(A > B) {
return 1*f;
}
return 0;
});
function getVal(elm){
var v = $(elm).children('td').eq(n).text().toUpperCase();
if($.isNumeric(v)){
v = parseInt(v,10);
}
return v;
}
$.each(rows, function(index, row) {
$('#mytable').children('tbody').append(row);
});
}
var f_sl = 1; // flag to toggle the sorting order
var f_nm = 1; // flag to toggle the sorting order
$("#sl").click(function(){
f_sl *= -1; // toggle the sorting order
var n = $(this).prevAll().length;
sortTable(f_sl,n);
});
$("#nm").click(function(){
f_nm *= -1; // toggle the sorting order
var n = $(this).prevAll().length;
sortTable(f_nm,n);
});
Hope this helps.
I think this might help you:
Here is the JSFiddle demo:
And here is the code:
var stIsIE = /*@cc_on!@*/ false;_x000D_
sorttable = {_x000D_
init: function() {_x000D_
if (arguments.callee.done) return;_x000D_
arguments.callee.done = true;_x000D_
if (_timer) clearInterval(_timer);_x000D_
if (!document.createElement || !document.getElementsByTagName) return;_x000D_
sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;_x000D_
forEach(document.getElementsByTagName('table'), function(table) {_x000D_
if (table.className.search(/\bsortable\b/) != -1) {_x000D_
sorttable.makeSortable(table);_x000D_
}_x000D_
});_x000D_
},_x000D_
makeSortable: function(table) {_x000D_
if (table.getElementsByTagName('thead').length == 0) {_x000D_
the = document.createElement('thead');_x000D_
the.appendChild(table.rows[0]);_x000D_
table.insertBefore(the, table.firstChild);_x000D_
}_x000D_
if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];_x000D_
if (table.tHead.rows.length != 1) return;_x000D_
sortbottomrows = [];_x000D_
for (var i = 0; i < table.rows.length; i++) {_x000D_
if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {_x000D_
sortbottomrows[sortbottomrows.length] = table.rows[i];_x000D_
}_x000D_
}_x000D_
if (sortbottomrows) {_x000D_
if (table.tFoot == null) {_x000D_
tfo = document.createElement('tfoot');_x000D_
table.appendChild(tfo);_x000D_
}_x000D_
for (var i = 0; i < sortbottomrows.length; i++) {_x000D_
tfo.appendChild(sortbottomrows[i]);_x000D_
}_x000D_
delete sortbottomrows;_x000D_
}_x000D_
headrow = table.tHead.rows[0].cells;_x000D_
for (var i = 0; i < headrow.length; i++) {_x000D_
if (!headrow[i].className.match(/\bsorttable_nosort\b/)) {_x000D_
mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);_x000D_
if (mtch) {_x000D_
override = mtch[1];_x000D_
}_x000D_
if (mtch && typeof sorttable["sort_" + override] == 'function') {_x000D_
headrow[i].sorttable_sortfunction = sorttable["sort_" + override];_x000D_
} else {_x000D_
headrow[i].sorttable_sortfunction = sorttable.guessType(table, i);_x000D_
}_x000D_
headrow[i].sorttable_columnindex = i;_x000D_
headrow[i].sorttable_tbody = table.tBodies[0];_x000D_
dean_addEvent(headrow[i], "click", sorttable.innerSortFunction = function(e) {_x000D_
_x000D_
if (this.className.search(/\bsorttable_sorted\b/) != -1) {_x000D_
sorttable.reverse(this.sorttable_tbody);_x000D_
this.className = this.className.replace('sorttable_sorted',_x000D_
'sorttable_sorted_reverse');_x000D_
this.removeChild(document.getElementById('sorttable_sortfwdind'));_x000D_
sortrevind = document.createElement('span');_x000D_
sortrevind.id = "sorttable_sortrevind";_x000D_
sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▴';_x000D_
this.appendChild(sortrevind);_x000D_
return;_x000D_
}_x000D_
if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {_x000D_
sorttable.reverse(this.sorttable_tbody);_x000D_
this.className = this.className.replace('sorttable_sorted_reverse',_x000D_
'sorttable_sorted');_x000D_
this.removeChild(document.getElementById('sorttable_sortrevind'));_x000D_
sortfwdind = document.createElement('span');_x000D_
sortfwdind.id = "sorttable_sortfwdind";_x000D_
sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾';_x000D_
this.appendChild(sortfwdind);_x000D_
return;_x000D_
}_x000D_
theadrow = this.parentNode;_x000D_
forEach(theadrow.childNodes, function(cell) {_x000D_
if (cell.nodeType == 1) {_x000D_
cell.className = cell.className.replace('sorttable_sorted_reverse', '');_x000D_
cell.className = cell.className.replace('sorttable_sorted', '');_x000D_
}_x000D_
});_x000D_
sortfwdind = document.getElementById('sorttable_sortfwdind');_x000D_
if (sortfwdind) {_x000D_
sortfwdind.parentNode.removeChild(sortfwdind);_x000D_
}_x000D_
sortrevind = document.getElementById('sorttable_sortrevind');_x000D_
if (sortrevind) {_x000D_
sortrevind.parentNode.removeChild(sortrevind);_x000D_
}_x000D_
_x000D_
this.className += ' sorttable_sorted';_x000D_
sortfwdind = document.createElement('span');_x000D_
sortfwdind.id = "sorttable_sortfwdind";_x000D_
sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾';_x000D_
this.appendChild(sortfwdind);_x000D_
row_array = [];_x000D_
col = this.sorttable_columnindex;_x000D_
rows = this.sorttable_tbody.rows;_x000D_
for (var j = 0; j < rows.length; j++) {_x000D_
row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];_x000D_
}_x000D_
row_array.sort(this.sorttable_sortfunction);_x000D_
tb = this.sorttable_tbody;_x000D_
for (var j = 0; j < row_array.length; j++) {_x000D_
tb.appendChild(row_array[j][1]);_x000D_
}_x000D_
delete row_array;_x000D_
});_x000D_
}_x000D_
}_x000D_
},_x000D_
_x000D_
guessType: function(table, column) {_x000D_
sortfn = sorttable.sort_alpha;_x000D_
for (var i = 0; i < table.tBodies[0].rows.length; i++) {_x000D_
text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);_x000D_
if (text != '') {_x000D_
if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {_x000D_
return sorttable.sort_numeric;_x000D_
}_x000D_
possdate = text.match(sorttable.DATE_RE)_x000D_
if (possdate) {_x000D_
first = parseInt(possdate[1]);_x000D_
second = parseInt(possdate[2]);_x000D_
if (first > 12) {_x000D_
return sorttable.sort_ddmm;_x000D_
} else if (second > 12) {_x000D_
return sorttable.sort_mmdd;_x000D_
} else {_x000D_
sortfn = sorttable.sort_ddmm;_x000D_
}_x000D_
}_x000D_
}_x000D_
}_x000D_
return sortfn;_x000D_
},_x000D_
getInnerText: function(node) {_x000D_
if (!node) return "";_x000D_
hasInputs = (typeof node.getElementsByTagName == 'function') &&_x000D_
node.getElementsByTagName('input').length;_x000D_
if (node.getAttribute("sorttable_customkey") != null) {_x000D_
return node.getAttribute("sorttable_customkey");_x000D_
} else if (typeof node.textContent != 'undefined' && !hasInputs) {_x000D_
return node.textContent.replace(/^\s+|\s+$/g, '');_x000D_
} else if (typeof node.innerText != 'undefined' && !hasInputs) {_x000D_
return node.innerText.replace(/^\s+|\s+$/g, '');_x000D_
} else if (typeof node.text != 'undefined' && !hasInputs) {_x000D_
return node.text.replace(/^\s+|\s+$/g, '');_x000D_
} else {_x000D_
switch (node.nodeType) {_x000D_
case 3:_x000D_
if (node.nodeName.toLowerCase() == 'input') {_x000D_
return node.value.replace(/^\s+|\s+$/g, '');_x000D_
}_x000D_
case 4:_x000D_
return node.nodeValue.replace(/^\s+|\s+$/g, '');_x000D_
break;_x000D_
case 1:_x000D_
case 11:_x000D_
var innerText = '';_x000D_
for (var i = 0; i < node.childNodes.length; i++) {_x000D_
innerText += sorttable.getInnerText(node.childNodes[i]);_x000D_
}_x000D_
return innerText.replace(/^\s+|\s+$/g, '');_x000D_
break;_x000D_
default:_x000D_
return '';_x000D_
}_x000D_
}_x000D_
},_x000D_
reverse: function(tbody) {_x000D_
// reverse the rows in a tbody_x000D_
newrows = [];_x000D_
for (var i = 0; i < tbody.rows.length; i++) {_x000D_
newrows[newrows.length] = tbody.rows[i];_x000D_
}_x000D_
for (var i = newrows.length - 1; i >= 0; i--) {_x000D_
tbody.appendChild(newrows[i]);_x000D_
}_x000D_
delete newrows;_x000D_
},_x000D_
sort_numeric: function(a, b) {_x000D_
aa = parseFloat(a[0].replace(/[^0-9.-]/g, ''));_x000D_
if (isNaN(aa)) aa = 0;_x000D_
bb = parseFloat(b[0].replace(/[^0-9.-]/g, ''));_x000D_
if (isNaN(bb)) bb = 0;_x000D_
return aa - bb;_x000D_
},_x000D_
sort_alpha: function(a, b) {_x000D_
if (a[0] == b[0]) return 0;_x000D_
if (a[0] < b[0]) return -1;_x000D_
return 1;_x000D_
},_x000D_
sort_ddmm: function(a, b) {_x000D_
mtch = a[0].match(sorttable.DATE_RE);_x000D_
y = mtch[3];_x000D_
m = mtch[2];_x000D_
d = mtch[1];_x000D_
if (m.length == 1) m = '0' + m;_x000D_
if (d.length == 1) d = '0' + d;_x000D_
dt1 = y + m + d;_x000D_
mtch = b[0].match(sorttable.DATE_RE);_x000D_
y = mtch[3];_x000D_
m = mtch[2];_x000D_
d = mtch[1];_x000D_
if (m.length == 1) m = '0' + m;_x000D_
if (d.length == 1) d = '0' + d;_x000D_
dt2 = y + m + d;_x000D_
if (dt1 == dt2) return 0;_x000D_
if (dt1 < dt2) return -1;_x000D_
return 1;_x000D_
},_x000D_
sort_mmdd: function(a, b) {_x000D_
mtch = a[0].match(sorttable.DATE_RE);_x000D_
y = mtch[3];_x000D_
d = mtch[2];_x000D_
m = mtch[1];_x000D_
if (m.length == 1) m = '0' + m;_x000D_
if (d.length == 1) d = '0' + d;_x000D_
dt1 = y + m + d;_x000D_
mtch = b[0].match(sorttable.DATE_RE);_x000D_
y = mtch[3];_x000D_
d = mtch[2];_x000D_
m = mtch[1];_x000D_
if (m.length == 1) m = '0' + m;_x000D_
if (d.length == 1) d = '0' + d;_x000D_
dt2 = y + m + d;_x000D_
if (dt1 == dt2) return 0;_x000D_
if (dt1 < dt2) return -1;_x000D_
return 1;_x000D_
},_x000D_
shaker_sort: function(list, comp_func) {_x000D_
var b = 0;_x000D_
var t = list.length - 1;_x000D_
var swap = true;_x000D_
while (swap) {_x000D_
swap = false;_x000D_
for (var i = b; i < t; ++i) {_x000D_
if (comp_func(list[i], list[i + 1]) > 0) {_x000D_
var q = list[i];_x000D_
list[i] = list[i + 1];_x000D_
list[i + 1] = q;_x000D_
swap = true;_x000D_
}_x000D_
}_x000D_
t--;_x000D_
_x000D_
if (!swap) break;_x000D_
_x000D_
for (var i = t; i > b; --i) {_x000D_
if (comp_func(list[i], list[i - 1]) < 0) {_x000D_
var q = list[i];_x000D_
list[i] = list[i - 1];_x000D_
list[i - 1] = q;_x000D_
swap = true;_x000D_
}_x000D_
}_x000D_
b++;_x000D_
_x000D_
}_x000D_
}_x000D_
}_x000D_
if (document.addEventListener) {_x000D_
document.addEventListener("DOMContentLoaded", sorttable.init, false);_x000D_
}_x000D_
/* for Internet Explorer */_x000D_
/*@cc_on @*/_x000D_
/*@if (@_win32)_x000D_
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");_x000D_
var script = document.getElementById("__ie_onload");_x000D_
script.onreadystatechange = function() {_x000D_
if (this.readyState == "complete") {_x000D_
sorttable.init(); // call the onload handler_x000D_
}_x000D_
};_x000D_
/*@end @*/_x000D_
/* for Safari */_x000D_
if (/WebKit/i.test(navigator.userAgent)) { // sniff_x000D_
var _timer = setInterval(function() {_x000D_
if (/loaded|complete/.test(document.readyState)) {_x000D_
sorttable.init(); // call the onload handler_x000D_
}_x000D_
}, 10);_x000D_
}_x000D_
/* for other browsers */_x000D_
window.onload = sorttable.init;_x000D_
_x000D_
function dean_addEvent(element, type, handler) {_x000D_
if (element.addEventListener) {_x000D_
element.addEventListener(type, handler, false);_x000D_
} else {_x000D_
if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;_x000D_
if (!element.events) element.events = {};_x000D_
var handlers = element.events[type];_x000D_
if (!handlers) {_x000D_
handlers = element.events[type] = {};_x000D_
if (element["on" + type]) {_x000D_
handlers[0] = element["on" + type];_x000D_
}_x000D_
}_x000D_
handlers[handler.$$guid] = handler;_x000D_
element["on" + type] = handleEvent;_x000D_
}_x000D_
};_x000D_
dean_addEvent.guid = 1;_x000D_
_x000D_
function removeEvent(element, type, handler) {_x000D_
if (element.removeEventListener) {_x000D_
element.removeEventListener(type, handler, false);_x000D_
} else {_x000D_
if (element.events && element.events[type]) {_x000D_
delete element.events[type][handler.$$guid];_x000D_
}_x000D_
}_x000D_
};_x000D_
_x000D_
function handleEvent(event) {_x000D_
var returnValue = true;_x000D_
event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);_x000D_
var handlers = this.events[event.type];_x000D_
for (var i in handlers) {_x000D_
this.$$handleEvent = handlers[i];_x000D_
if (this.$$handleEvent(event) === false) {_x000D_
returnValue = false;_x000D_
}_x000D_
}_x000D_
return returnValue;_x000D_
};_x000D_
_x000D_
function fixEvent(event) {_x000D_
event.preventDefault = fixEvent.preventDefault;_x000D_
event.stopPropagation = fixEvent.stopPropagation;_x000D_
return event;_x000D_
};_x000D_
fixEvent.preventDefault = function() {_x000D_
this.returnValue = false;_x000D_
};_x000D_
fixEvent.stopPropagation = function() {_x000D_
this.cancelBubble = true;_x000D_
}_x000D_
if (!Array.forEach) {_x000D_
Array.forEach = function(array, block, context) {_x000D_
for (var i = 0; i < array.length; i++) {_x000D_
block.call(context, array[i], i, array);_x000D_
}_x000D_
};_x000D_
}_x000D_
Function.prototype.forEach = function(object, block, context) {_x000D_
for (var key in object) {_x000D_
if (typeof this.prototype[key] == "undefined") {_x000D_
block.call(context, object[key], key, object);_x000D_
}_x000D_
}_x000D_
};_x000D_
String.forEach = function(string, block, context) {_x000D_
Array.forEach(string.split(""), function(chr, index) {_x000D_
block.call(context, chr, index, string);_x000D_
});_x000D_
};_x000D_
var forEach = function(object, block, context) {_x000D_
if (object) {_x000D_
var resolve = Object;_x000D_
if (object instanceof Function) {_x000D_
resolve = Function;_x000D_
} else if (object.forEach instanceof Function) {_x000D_
object.forEach(block, context);_x000D_
return;_x000D_
} else if (typeof object == "string") {_x000D_
resolve = String;_x000D_
} else if (typeof object.length == "number") {_x000D_
resolve = Array;_x000D_
}_x000D_
resolve.forEach(object, block, context);_x000D_
}_x000D_
}
_x000D_
table.sortable thead {_x000D_
background-color: #eee;_x000D_
color: #666666;_x000D_
font-weight: bold;_x000D_
cursor: default;_x000D_
}
_x000D_
<table class="sortable">_x000D_
<thead>_x000D_
<tr>_x000D_
<th>S.L.</th>_x000D_
<th>name</th>_x000D_
<th>Goal</th>_x000D_
</tr>_x000D_
</thead>_x000D_
<tbody>_x000D_
<tr>_x000D_
<td>1</td>_x000D_
<td>Ronaldo</td>_x000D_
<td>120</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>2</td>_x000D_
<td>Messi</td>_x000D_
<td>66</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>3</td>_x000D_
<td>Ribery</td>_x000D_
<td>10</td>_x000D_
</tr>_x000D_
<tr>_x000D_
<td>4</td>_x000D_
<td>Bale</td>_x000D_
<td>22</td>_x000D_
</tr>_x000D_
</tbody>_x000D_
</table>
_x000D_
JS is used here without any other JQuery Plugin.
I found @naota's solution useful, and extended it to use dates as well
//taken from StackOverflow:
//https://stackoverflow.com/questions/3880615/how-can-i-determine-whether-a-given-string-represents-a-date
function isDate(val) {
var d = new Date(val);
return !isNaN(d.valueOf());
}
var getVal = function(elm, n){
var v = $(elm).children('td').eq(n).text().toUpperCase();
if($.isNumeric(v)){
v = parseFloat(v,10);
return v;
}
if (isDate(v)) {
v = new Date(v);
return v;
}
return v;
}
You can use jQuery DataTables plugin for applying column sorting in desired way.
Source: Stackoverflow.com