Making HTML tables sortable without backend shenanigans

We’ve all wanted to do it – to just have a table sortable on the front end. You click on the column and the table sorts to that column.

We don’t want to write heaps of code on the back end that when you click on a column you have to adjust your queryset.

Here is the simplest way I’ve found so far to enable a table to be sorted by columns using JavaScript:

Introducing Sortable

Go and download the Sortable repository.

Now there are two files there that you need to include:

<link href="sortable.css" rel="stylesheet" />
<script src="sortable.js"></script>

In my Django repo they look something like this:

The Javascript file:

<script src="{% static 'js/sortable.js' %}"></script>

And I striped down the CSS and put it into my Project.css file:

/* ==================== Sortable */
.sortable th:hover::after {
  color: inherit;
  font-size: 1.2em;
  content: '\00a0\025B8';
}

.sortable th::after {
  font-size: 1.2em;
  color: transparent;
  content: '\00a0\025B8';
}

.sortable th.dir-d::after {
  color: inherit;
  content: '\00a0\025BE';
}

.sortable th.dir-u::after {
  color: inherit;
  content: '\00a0\025B4';
}

th.no-sort {
  pointer-events: none;
}

th.no-sort::after {
  content: none;
}
/* ==================== End Sortable */

Now you just add the sortable class to your table like so (for an example I assume you have context variable called users):

<table class="sortable">
    <thead>
        <tr>
            <th>Username</th>
            <th>Created</th>
        </tr>
    </thead>
    <tbody>
        {%  for user in users %}
            <tr>
                <td>{{ user.username }}</td>
                <td>{{ user.created }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

So what’s the catch?

Well the only catch I could find was that you HAVE to have <thead></thead> and <tbody></tbody> tags for it to work.

What about dates?

Sometime you want to sort by a value that is not the displayed value in the table. Dates are an example – we display them dd mmm yyyy but we want to sort them yyyymmdd

Sortable allows you to add the “data-sort” attribute to your table like so:

<td data-sort="{{user.created | date:"Ymd"}}">
    {{ user.created | date:"d M Y"}}           
</td>

Example

Here’s an example: https://tofsjonas.github.io/sortable/

Conclusion

I found getting sortable where I wanted it with CSS styling and that gotcha about <thead></thead> took a bit of time.

But now it’s in my repo – I just put the sortable class to my table and it’s immediately sortable!

I love it – my users love it – and I’m sure you’ll love it!

Leave a Reply