
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:
- Fetches all the rows of the table and stores the row HTML and the value from the column in a multi-dimensional array.
- 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).
- 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).
- 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>
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
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.
Thanks John, will update the guide!
How to work out for date
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)
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.
this code are not working
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.
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.
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
What would be the point of this? I dont see any reason for this or feel it would make running the function extra hard. I guess what would be better is an ignorerowsfromstart and ignorerowsfromend so you can for example say ignore the first 3 rows, and ignore the last 2 rows if you had anything there static you didnt want being shifted. Will have a think about that and see what I can do. I do want to extend this so you can apply “hidden” raw data for sorting, so for example you can have nice formatted dates visible… Read more »
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 »
excuse me: change
add an invisible but
formattablecolumn in aaaammddto
add an invisible but sortable column in aaaammdd