Web Design. Web Development. Web Hosting.
0 items

Sort Table By Column using JavaScript – Text Sort & Number Sort

Need some help? We are here for you!

We have a very friendly service - Come and chat to us and let us know what you need, we work for an hourly fee and can also provide you a no obligation quote and begin work immediately in most cases. Click "Request Support" or use our Live Chat.

Request support

So recently I wanted to be able to sort a HTML table column using Javascript, I wanted to be able to sort ASC or DESC flipping the order on multiple clicks of the column. The table was going to be pretty big so another important factor was speed, it had to run as fast as possible. This last detail was more of a gotcha because I wrote a script to do the sorting but it was VERY SLOW on large tables so I had to go back to the drawing board and refine my code until the table size was no longer a huge performance hit.

What I’ve come up with below is extremely fast, it will still obviously slow down more and more the bigger and more complex your tables are, but this is working fine with a table with 10 columns and over 2000 rows with only a second of runtime between click and result. Much better than 5-10 minutes with the code I first wrote.

So what this code is doing in a nutshell:

  1. Fetches all the rows of the table and stores the row HTML and the value from the column in a multi-dimensional array.
  2. Sorts the JavaScript array based on the value in the multi-dimensional array (it will detect if the values are strings or numbers and sorts accordingly), without touching the Dom at all (this is where the speed was improved).
  3. overwrites each cell in the table with the new data (before I was clearing the table and adding the new data in but this apparently causes some issues in IE).
  4. Appends a caret to the column header so you know you have sorted that column and in which direction (ASC or DESC).

Here is an example code below, all you need to do is match the ID on the table tag with the ID mentioned in the JS, add sortTable to each column TD you want sortable (make sure you use correct column depth starting at 0) and make sure you code your tables properly, ie. with a thead and tbody.

 

Javascript

var asc = 0;
function sort_table(table, col)
{
 $('.sortorder').remove();
 if (asc == 2) {asc = -1;} else {asc = 2;}
 var rows = table.tBodies[0].rows;
 var rlen = rows.length-1;
 var arr = new Array();
 var i, j, cells, clen;
 // fill the array with values from the table
 for(i = 0; i < rlen; i++)
 {
 cells = rows[i].cells;
 clen = cells.length;
 arr[i] = new Array();
 for(j = 0; j < clen; j++) { arr[i][j] = cells[j].innerHTML; }
 }
 // sort the array by the specified column number (col) and order (asc)
 arr.sort(function(a, b)
 {
 var retval=0;
 var col1 = a[col].toLowerCase().replace(',', '').replace('$', '').replace(' usd', '')
 var col2 = b[col].toLowerCase().replace(',', '').replace('$', '').replace(' usd', '')
 var fA=parseFloat(col1);
 var fB=parseFloat(col2);
 if(col1 != col2)
 {
 if((fA==col1) && (fB==col2) ){ retval=( fA > fB ) ? asc : -1*asc; } //numerical
 else { retval=(col1 > col2) ? asc : -1*asc;}
 }
 return retval; 
 });
 for(var rowidx=0;rowidx<rlen;rowidx++)
 {
 for(var colidx=0;colidx<arr[rowidx].length;colidx++){ table.tBodies[0].rows[rowidx].cells[colidx].innerHTML=arr[rowidx][colidx]; }
 }
 
 hdr = table.rows[0].cells[col];
 if (asc == -1) {
 $(hdr).html($(hdr).html() + '<span class="sortorder">▲</span>');
 } else {
 $(hdr).html($(hdr).html() + '<span class="sortorder">▼</span>');
 }
}


function sortTable(n) {
 sort_table(document.getElementById("myTable"), n);
}

 

HTML Example

<table>
 <thead>
 <tr style="cursor:pointer">
 <td onclick="sortTable(0);">head 1</td>
 <td onclick="sortTable(1);">head 2</td>
 <td onclick="sortTable(2);">head 3</td>
 <td onclick="sortTable(3);">head 4</td>
 </tr>
 </thead>
 <tbody>
 <tr>
 <td>a</td>
 <td>3</td>
 <td>b</td>
 <td>2</td>
 </tr>
 <tr>
 <td>c</td>
 <td>1</td>
 <td>c</td>
 <td>3</td>
 </tr>
 <tr>
 <td>b</td>
 <td>2</td>
 <td>a</td>
 <td>1</td>
 </tr>
 </tbody>
</table>
2.7 6 votes
Article Rating
Need some help? We are here for you!

We have a very friendly service - Come and chat to us and let us know what you need, we work for an hourly fee and can also provide you a no obligation quote and begin work immediately in most cases. Click "Request Support" or use our Live Chat.

Request support
Author: Dean WilliamsProfessional PHP Web Developer with expertise in OpenCart Web Development, WordPress Web Development, Bespoke Systems - also a seasoned Linux Server Administrator.


Subscribe
Notify of
12 Comments
Inline Feedbacks
View all comments
John
4 years ago

Useful thanks, just had to add an id of “myTable” to the table. Also had to remove -1 from the rlen variable to be…

var rlen = rows.length;

This was preventing the last row from being sorted.

shanmugavel
4 years ago

How to work out for date

Admin
Reply to  shanmugavel
4 years ago

you could convert the date to a timestamp which would then be sortable using a line of code such as:

let toTimestamp = strDate => Date.parse(strDate)

salvatore fusto
Reply to  Josh Burley
3 years ago

another trick is to add an invisible colum (i.e. display:none) containing the formatted date value (i.e. yyyy.mm.dd) and sort on this column.

vermadeals
4 years ago

this code are not working

Abhay
4 years ago

Hey John I just want when page load that same time one specific column of table will show in ASC order and rest of all column automatically work according that.

FEARIV
3 years ago

Very useful indeed, most code I found removed the used id/class from the rows, causing the functionality of my live server-table to break.
Also I had to remove the -1 from the rlen to include last row, so seems article isn’t updated yet.

salvatore fusto
Reply to  FEARIV
3 years ago

a simple but usefull update may be to add two other parameters to the sort_table function, one for the first row and one for the last row to sort so: function sortTable(table, col, startRow, endRow).
of course the code will be updated to order from startRow to endRow, so imho this function will be more abstact

salvatore fusto
Reply to  Dean Williams
3 years ago

Dean, thanks for reply. for the first point, the ignoreRows… or startRow and endRow are similar, so you can implement this solution, in this way you can have one or more static hrader row, say titles, an static footers, say totals. About formatting data, in my countruy (Italy) date is (generally) displayed as dd/mm/yyyy (today 13/10/2021) so i use to display a non-sortabe date colums in italian format and add an invisible but formattable column in aaaammdd format so correctly managing date column: when i click to sort a date column, i pass the id of the invisible colums. this… Read more »

salvatore fusto
Reply to  salvatore fusto
3 years ago

excuse me: change
add an invisible but formattable column in aaaammdd
to
add an invisible but sortable column in aaaammdd



Share this page..

Let's begin your journey...

Get in touch us now to begin your journey to having a beautifully crafted mobile responsive website. If you're still unsure what we could do for you then take a look at our why us page which includes reviews, or take a look at our portfolio.

We can work on improving existing websites or craft a new stylish website making your business stand out.

You could always catch us by email, telephone, Skype or live chat to us below.


    12
    0
    Would love your thoughts, please comment.x
    ()
    x