Skip to content

Instantly share code, notes, and snippets.

@scopevale
Created January 23, 2012 14:41
Show Gist options
  • Save scopevale/1663452 to your computer and use it in GitHub Desktop.
Save scopevale/1663452 to your computer and use it in GitHub Desktop.
jsFiddle demo - Table Sort (vanilla JS)
table {
border: solid 1px #fc0;
border-collapse: collapse;
}
table caption {
font-weight: bold;
font-size: 125%;
text-transform: uppercase;
}
.footnote {
font-size: 75%;
color: #666;
}
table caption,
table th,
table td,
.footnote {
font-family: Arial, Helvetica, sans-serif;
padding: .5em;
}
table td {
border: solid 1px #c96;
}
table th {
background-color: #ec9;
color: #630;
border-bottom: solid 1px #c96;
}
table thead th {
background: #fea;
border-bottom: solid 3px #630;
}
table thead th a {
color: #630;
display: block;
padding: 0 17px;
background: #fea url(http://wps.scopevale.net/scripts/css/tablesort/arrow-up.gif) no-repeat right center;
}
table thead th.asc a {
background: #fea url(http://wps.scopevale.net/scripts/css/tablesort/arrow-up-sel.gif) no-repeat right center;
}
table thead th.dsc a {
background: #fea url(http://wps.scopevale.net/scripts/css/tablesort/arrow-dn-sel.gif) no-repeat right center;
}
<table id="sales" summary="Quarterly Sales (stated in millions of dollars)">
<caption>Quarterly Sales*</caption>
<thead>
<tr>
<th>Companies</th>
<th>Q1</th>
<th>Q2</th>
<th>Q3</th>
<th>Q4</th>
</tr>
</thead>
<tbody>
<tr>
<th>Company A</th>
<td>$621</td>
<td>$942</td>
<td>$224</td>
<td>$486</td>
</tr>
<tr>
<th>Company B</th>
<td>$147</td>
<td>$1,325</td>
<td>$683</td>
<td>$524</td>
</tr>
<tr>
<th>Company C</th>
<td>$135</td>
<td>$2,342</td>
<td>$33</td>
<td>$464</td>
</tr>
<tr>
<th>Company D</th>
<td>$164</td>
<td>$332</td>
<td>$331</td>
<td>$438</td>
</tr>
<tr>
<th>Company E</th>
<td>$199</td>
<td>$902</td>
<td>$336</td>
<td>$1,427</td>
</tr>
</tbody>
</table>
<p class="footnote">*Stated in millions of dollars</p>
window.onload = function() {
var sales = new TableSort("sales");
};
name: jsFiddle/Gist TableSort demo
description: jsFiddle demo hosted on Gist
authors:
- Gary Smith
title:
- JS Fiddle - jsFiddle/Gist integration demo - students
resources:
- /js/empty.js
- /css/normalize.css
- https://raw.github.com/gist/1663452/7f6270af1e695cea8198164979d726cae566f026/tablesort.js
normalize_css: no
...
function TableSort(id) {
this.tbl = document.getElementById(id);
this.lastSortedTh = null;
if (this.tbl && this.tbl.nodeName == "TABLE") {
var headings = this.tbl.tHead.rows[0].cells;
for (var i=0; headings[i]; i++) {
if (headings[i].className.match(/asc|dsc/)) {
this.lastSortedTh = headings[i];
}
}
this.makeSortable();
}
}
TableSort.prototype.makeSortable = function () {
var headings = this.tbl.tHead.rows[0].cells;
for (var i=0; headings[i]; i++) {
headings[i].cIdx = i;
var a = document.createElement("a");
a.href = "#";
a.innerHTML = headings[i].innerHTML;
a.onclick = function (that) {
return function () {
that.sortCol(this);
return false;
}
}(this);
headings[i].innerHTML = "";
headings[i].appendChild(a);
}
}
TableSort.prototype.sortCol = function (el) {
/*
* Get cell data for column that is to be sorted from HTML table
*/
var rows = this.tbl.rows;
var alpha = [], numeric = [];
var aIdx = 0, nIdx = 0;
var th = el.parentNode;
var cellIndex = th.cIdx;
for (var i=1; rows[i]; i++) {
var cell = rows[i].cells[cellIndex];
var content = cell.textContent ? cell.textContent : cell.innerText;
/*
* Split data into two separate arrays, one for numeric content and
* one for everything else (alphabetic). Store both the actual data
* that will be used for comparison by the sort algorithm (thus the need
* to parseFloat() the numeric data) as well as a reference to the
* element's parent row. The row reference will be used after the new
* order of content is determined in order to actually reorder the HTML
* table's rows.
*/
var num = content.replace(/(\$|\,|\s)/g, "");
if (parseFloat(num) == num) {
numeric[nIdx++] = {
value: Number(num),
row: rows[i]
}
} else {
alpha[aIdx++] = {
value: content,
row: rows[i]
}
}
}
/*
* Sort according to direction (ascending or descending)
*/
var col = [], top, bottom;
if (th.className.match("asc")) {
top = bubbleSort(alpha, -1);
bottom = bubbleSort(numeric, -1);
th.className = th.className.replace(/asc/, "dsc");
} else {
top = bubbleSort(numeric, 1);
bottom = bubbleSort(alpha, 1);
if (th.className.match("dsc")) {
th.className = th.className.replace(/dsc/, "asc");
} else {
th.className += "asc";
}
}
/*
* Clear asc/dsc class names from the last sorted column's th if it isnt the
* same as the one that was just clicked
*/
if (this.lastSortedTh && th != this.lastSortedTh) {
this.lastSortedTh.className = this.lastSortedTh.className.replace(/dsc|asc/g, "");
}
this.lastSortedTh = th;
/*
* Reorder HTML table based on new order of data found in the col array
*/
col = top.concat(bottom);
var tBody = this.tbl.tBodies[0];
for (var i=0; col[i]; i++) {
tBody.appendChild(col[i].row);
}
}
function bubbleSort(arr, dir) {
// Pre-calculate directional information
var start, end;
if (dir === 1) {
start = 0;
end = arr.length;
} else if (dir === -1) {
start = arr.length-1;
end = -1;
}
// Bubble sort: http://en.wikipedia.org/wiki/Bubble_sort
var unsorted = true;
while (unsorted) {
unsorted = false;
for (var i=start; i!=end; i=i+dir) {
if (arr[i+dir] && arr[i].value > arr[i+dir].value) {
var a = arr[i];
var b = arr[i+dir];
var c = a;
arr[i] = b;
arr[i+dir] = c;
unsorted = true;
}
}
}
return arr;
}
@scopevale
Copy link
Author

@SunboX
Copy link

SunboX commented Aug 12, 2014

@azeemh
Copy link

azeemh commented Jun 12, 2017

neither of your fiddles work @scopevale @SunboX

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment