jQuery Table Sorting: Sort Data on Header Click

In this tutorial, we'll quickly discuss table sorting with jQuery. We'll create a few quick functions that will sort table data on header click without the use of any additional plugins or bloated code. Let's get started!

The Table Data

Let's put together an HTML table containing some user IDs, a first name, and a last name:

<table>
<caption>Users</caption>

<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th class="no-sort"></th>
</tr>
</thead>

<tbody>
<tr>
<td>1</td>
<td>Luke</td>
<td>Skywalker</td>
<td>X</td>
</tr>
<tr>
<td>2</td>
<td>Leia</td>
<td>Organa</td>
<td>X</td>
</tr>
<tr>
<td>3</td>
<td>Anakin</td>
<td>Skywalker</td>
<td>X</td>
</tr>
</tbody>
</table>

Notice that we've separated our table headings from the data in the body. This is crucial to ensure that, when sorting data, the table headings don't get sorted inadvertently. You could also do the same with the table footer by using a tfoot for separation.

The Table Sort Click Event

Now that we have our table data, let's get right into the jQuery table sorting code.

We need to create a click event to the table headers, excluding any columns with the no-sort class:

$(document).on("click", "table thead tr th:not(.no-sort)", function() {
var table = $(this).parents("table");
var rows = $(this).parents("table").find("tbody tr").toArray().sort(TableComparer($(this).index()));
var dir = ($(this).hasClass("sort-asc")) ? "desc" : "asc";

if (dir == "desc") {
rows = rows.reverse();
}

for (var i = 0; i < rows.length; i++) {
table.append(rows[i]);
}

table.find("thead tr th").removeClass("sort-asc").removeClass("sort-desc");
$(this).removeClass("sort-asc").removeClass("sort-desc") .addClass("sort-" + dir);
});

In this function, we first identify the table and the data rows so we don't have to make extra calls to the DOM.

Next, we identify the sort direction. If the table heading has a class of sort-asc, then descending sort is assumed. Otherwise, we will sort our data numerically or alphabetically in ascending format.

If the sort direction is descending, then we reverse the table rows with rows.reverse().

Next, we loop through each table row and append to the table so they're sorted in the desired manner.

The last part does some class changes so clicking on the table heading multiple times will allow for different sorting directions. It also determines whether an up or down arrow is displayed in the table heading, illustrating the sort direction to the user.

Table Row Comparisons

The TableComparer() function call in our click event function is where the sorting magic happens. This function compares each table cell value with the surrounding values and sorts accordingly:

function TableComparer(index) {
return function(a, b) {
var val_a = TableCellValue(a, index);
var val_b = TableCellValue(b, index);
var result = ($.isNumeric(val_a) && $.isNumeric(val_b)) ? val_a - val_b : val_a.toString().localeCompare(val_b);

return result;
}
}

And the TableCellValue() that it's related to does exactly what it sounds like. It returns the value of the table cell:

function TableCellValue(row, index) {
return $(row).children("td").eq(index).text();
}

CSS Explanation

You can style the table any way you would like. But there are a few notable items to consider like displaying the sort arrow in the table heading, either up or down depending on the current sort direction of the selected column.

Here is the CSS that displays the arrows as needed:

table thead tr th:after {
position: absolute;
right: 2px;
}

table thead tr th.sort-asc:after {
content: "\25b4";
}

table thead tr th.sort-desc:after {
content: "\25be";
}

The first rule adds absolute positioning for the arrow on the right side of the table heading while the remaining two rules actually display the arrow in the table heading.

The jQuery table sorting click event function that we went over above is where the sort class is determined.

Conclusion

I've seen many examples and plugins over the years that are extremely complicated, bloated, and even unnecessary. This example takes the idea of table sorting with jQuery and simplifies it in a way that's easy to understand and keeps your code minimal.

You can download the full example on my GitHub. Enjoy!

Created: September 16, 2021

Comments

There are no comments yet. Start the conversation!

Leave a Comment

  Wrap code in a <code> and </code> block.
Subscribe to the newsletter to receive updates on new articles!
Remember my info