Table Sort with JavaScript
When an HTML table has much data, it can be useful to make the columns of information sortable.
The following technique uses JavaScript to sort the table rows by clicking on the column heading.
Here is an example table with all columns sortable. A second click on the same column header text reverses the sort.
Author | Title | Rating | Review Date |
---|---|---|---|
Orson Scott Card | The Memory Of Earth | 2 | 10/14/11 |
Sarah- |
Blessed Are The Cheesemakers | 9 | 1-12-2011 |
John Irving | The cider house rules | 6 | January 31, 11 |
Kate Atkinson | When will there be good news? | 7 | Nov. 31, 2001 |
Kathy Hogan Trocheck | Every Crooked Nanny | 2 | 10.21.21 |
Stieg Larsson | The Girl With The Dragon Tattoo | 2 | August 3, 2022 |
The JavaScript has one place to customize, the id value of the table tag. The table header text for each sortable column is linked to the JavaScript.
If you want to reproduce the example, here is the table code. (Certain parts that will be addressed later in this article are colored red.)
<table id="indextable" border="1" cellpadding="10" cellspacing="0" style="border-collapse:collapse;"> <thead> <tr> <th><a href="javascript:SortTable(0,'T');">Author</a></th> <th><a href="javascript:SortTable(1,'T');">Title</a></th> <th><a href="javascript:SortTable(2,'N');">Rating</a></th> <th><a href="javascript:SortTable(3,'D','mdy');">Review Date</a></th> </tr> </thead> <tbody> <tr> <td>Orson Scott Card</td> <td>The Memory Of Earth</td> <td align="center">2</td> <td>10/14/11</td> </tr> <tr> <td>Sarah-Kate Lynch</td> <td>Blessed Are The Cheesemakers</td> <td align="center">9</td> <td>1-12-2011</td> </tr> <tr> <td>John Irving</td> <td>The cider house rules</td> <td align="center">6</td> <td>January 31, 11</td> </tr> <tr> <td>Kate Atkinson</td> <td>When will there be good news?</td> <td align="center">7</td> <td>Nov. 31, 2001</td> </tr> <tr> <td>Kathy Hogan Trocheck</td> <td>Every Crooked Nanny</td> <td align="center">2</td> <td>10.21.21</td> </tr> <tr> <td>Stieg Larsson</td> <td>The Girl With The Dragon Tattoo</td> <td align="center">2</td> <td>August 3, 2022</td> </tr> </tbody> </table>
Here is the JavaScript that does the sorting when a header is clicked on. The JavaScript can go anywhere on the web page, in the HEAD or BODY area, above or below the form.
<script type="text/javascript">
/*
Willmaster Table Sort
Version 1.1
August 17, 2016
Updated GetDateSortingKey() to correctly sort two-digit months and days numbers with leading 0.
Version 1.0, July 3, 2011
Will Bontrager
https://www.willmaster.com/
Copyright 2011,2016 Will Bontrager Software, LLC
This software is provided "AS IS," without
any warranty of any kind, without even any
implied warranty such as merchantability
or fitness for a particular purpose.
Will Bontrager Software, LLC grants
you a royalty free license to use or
modify this software provided this
notice appears on all copies.
*/
//
// One placed to customize - The id value of the table tag.
var TableIDvalue = "indextable";
//
//////////////////////////////////////
var TableLastSortedColumn = -1;
function SortTable() {
var sortColumn = parseInt(arguments[0]);
var type = arguments.length > 1 ? arguments[1] : 'T';
var dateformat = arguments.length > 2 ? arguments[2] : '';
var table = document.getElementById(TableIDvalue);
var tbody = table.getElementsByTagName("tbody")[0];
var rows = tbody.getElementsByTagName("tr");
var arrayOfRows = new Array();
type = type.toUpperCase();
dateformat = dateformat.toLowerCase();
for(var i=0, len=rows.length; i<len; i++) {
arrayOfRows[i] = new Object;
arrayOfRows[i].oldIndex = i;
var celltext = rows[i].getElementsByTagName("td")[sortColumn].innerHTML.replace(/<[^>]*>/g,"");
if( type=='D' ) { arrayOfRows[i].value = GetDateSortingKey(dateformat,celltext); }
else {
var re = type=="N" ? /[^\.\-\+\d]/g : /[^a-zA-Z0-9]/g;
arrayOfRows[i].value = celltext.replace(re,"").substr(0,25).toLowerCase();
}
}
if (sortColumn == TableLastSortedColumn) { arrayOfRows.reverse(); }
else {
TableLastSortedColumn = sortColumn;
switch(type) {
case "N" : arrayOfRows.sort(CompareRowOfNumbers); break;
case "D" : arrayOfRows.sort(CompareRowOfNumbers); break;
default : arrayOfRows.sort(CompareRowOfText);
}
}
var newTableBody = document.createElement("tbody");
for(var i=0, len=arrayOfRows.length; i<len; i++) {
newTableBody.appendChild(rows[arrayOfRows[i].oldIndex].cloneNode(true));
}
table.replaceChild(newTableBody,tbody);
} // function SortTable()
function CompareRowOfText(a,b) {
var aval = a.value;
var bval = b.value;
return( aval == bval ? 0 : (aval > bval ? 1 : -1) );
} // function CompareRowOfText()
function CompareRowOfNumbers(a,b) {
var aval = /\d/.test(a.value) ? parseFloat(a.value) : 0;
var bval = /\d/.test(b.value) ? parseFloat(b.value) : 0;
return( aval == bval ? 0 : (aval > bval ? 1 : -1) );
} // function CompareRowOfNumbers()
function GetDateSortingKey(format,text) {
if( format.length < 1 ) { return ""; }
format = format.toLowerCase();
text = text.toLowerCase();
text = text.replace(/^[^a-z0-9]*/,"");
text = text.replace(/[^a-z0-9]*$/,"");
if( text.length < 1 ) { return ""; }
text = text.replace(/[^a-z0-9]+/g,",");
var date = text.split(",");
if( date.length < 3 ) { return ""; }
var d=0, m=0, y=0;
for( var i=0; i<3; i++ ) {
var ts = format.substr(i,1);
if( ts == "d" ) { d = date[i]; }
else if( ts == "m" ) { m = date[i]; }
else if( ts == "y" ) { y = date[i]; }
}
d = d.replace(/^0/,"");
if( d < 10 ) { d = "0" + d; }
if( /[a-z]/.test(m) ) {
m = m.substr(0,3);
switch(m) {
case "jan" : m = String(1); break;
case "feb" : m = String(2); break;
case "mar" : m = String(3); break;
case "apr" : m = String(4); break;
case "may" : m = String(5); break;
case "jun" : m = String(6); break;
case "jul" : m = String(7); break;
case "aug" : m = String(8); break;
case "sep" : m = String(9); break;
case "oct" : m = String(10); break;
case "nov" : m = String(11); break;
case "dec" : m = String(12); break;
default : m = String(0);
}
}
m = m.replace(/^0/,"");
if( m < 10 ) { m = "0" + m; }
y = parseInt(y);
if( y < 100 ) { y = parseInt(y) + 2000; }
return "" + String(y) + "" + String(m) + "" + String(d) + "";
} // function GetDateSortingKey()
</script>
The JavaScript has only one place to customize, the place marked in the JavaScript code. About 14 lines down from the top. The value of the variable TableIDvalue needs to be the id value of the table tag.
In the example, the table tag's id value is "indextable". Therefore, the line in the JavaScript reads
var TableIDvalue = "indextable";
Implementing Table Sort
To sort your own table, the table has to be prepared:
-
The table tag needs an id value, a value unique on the page. The JavaScript needs to have the id value specified in its one customization spot.
-
The header area of the table needs to be between thead tags and the body area needs to be between tbody tags.
-
Put the <thead> tag immediately before the <tr> tag that starts the table header area.
-
Put the </thead> tag immediately after the </tr> tag that ends the table header area.
-
Put the <tbody> tag immediately before the <tr> tag that starts the table body area.
-
Put the </tbody> tag immediately after the </tr> tag that ends the table body area.
Without the thead and tbody tags, the browser may refuse to sort or, if it does sort, the header row itself may be incorrectly sorted as if it was a table body row.
Use the code of the example table to see where the thead and tbody tags are placed.
-
-
The header text of the columns to be sort-enabled need a link. I'll show you how to make those links.
The JavaScript will sort columns of three different types of content:
- Text.
- Numbers.
- Dates.
The link for each type of content is addressed in its own section below.
The link for the header text depends on the type of content in the column to be sorted. The content type is sent to the JavaScript function doing the sorting.
The link also depends on the column number. The column number is sent to the JavaScript function doing the sorting. The left-most column is column number 0. The next is column 1. Then 2. And so forth in sequential order.
The links are regular A tag links. If you prefer, span tags may used, instead. See the Linking Without an "A" Tag article for how-to information.
Sorting Text Columns in a Table
Text content can be any type of text. Generally, it contains at least some alphabetical letters.
For sorting purposes, characters that are not letters or numbers are ignored. HTML tags are also ignored. If the content is larger than 25 visible alphanumeric characters, only the first 25 are considered when sorting.
Here is the text column sorting link href value (the column number is from the example table):
href="javascript:SortTable(0,'T');"
The JavaScript function SortTable() takes two parameters when sorting a text column:
-
The column number. The left-most column is number 0. The next column number 1. Then 2. And so forth.
-
The type of content. Specify "T" for text content.
Here is an example implementation:
<th><a href="javascript:SortTable(0,'T');">Author</a></th>
Sorting Number Columns in a Table
A column of numbers may have plain numbers, integers or decimal. The numbers may be accompanied with any symbols. It may contain a currency symbol, for example. Or a "%" character.
When a sort is done on numbers, the sorting ignores any characters except numbers, decimal points, minus signs, and plus signs.
Here is the number column sorting link href value (the column number is from the example table):
href="javascript:SortTable(2,'N');"
The JavaScript function SortTable() takes two parameters when sorting a number column:
-
The column number.
-
The type of content. Specify "N" for sorting a column of numbers.
Here is an example implementation:
<th><a href="javascript:SortTable(2,'N');">Rating</a></th>
Sorting Date Columns in a Table
Dates can be written in many different ways. Examples: 5.9.2012, 9/5/12,
The elements in a date are day, month, and year. Generally, the sequence is written as month-day-year or day-month-year.
For the sort to work on dates, these two items must be true:
-
The sequence of date elements is the same for every date in the column.
-
At least one non-alphanumeric character separates the date elements.
Special month date element consideration.
If a month name is used instead of its number, at least the first 3 letters must be used and it must be an English language month name. Month names are not case-sensitive. For example, "February", "FEB", and "Feb." may all be used instead of
(The JavaScript may be modified to accept other languages. The edit would be in the switch() statement of the GetDateSortingKey() function.)
Month names and month numbers may both be used in the same column of sortable dates.
Special year date element consideration.
If a one- or two-digit year is used, the year is assumed to begin with "20" for sorting purposes. Year 12 is assumed to be year 2012 for example. And year 3 is assumed to be year 2003.
Here is the date column sorting link href value (the column number is from the example table):
href="javascript:SortTable(3,'D','mdy');"
For sorting a column of dates, the JavaScript function SortTable() takes three parameters:
-
The column number.
-
The type of content. Specify "D" for sorting a column of dates.
-
The sequence of date elements. Use "mdy" for month-day-year and "dmy" for day-month-year. For other sequences, arrange the letters "d", "m", and "y" accordingly.
Here is an example implementation:
<th><a href="javascript:SortTable(3,'D','mdy');">Review Date</a></th>
The implementation may be tested when the first sortable column header text has been linked. Then, link the header text of any other columns to be made sortable.
Table Sorting
The JavaScript has one place to customize, the id value of the table tag. The table header text for each sortable column is linked to the JavaScript.
When the header text of a sortable column is clicked, the rows of the table are sorted according to the clicked column. A second click on the same column reverses the sort.
Use the HTML code of the example table as a guide for implementing your own table sort.
Will Bontrager