Skip to content

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!

7 thoughts on “Making HTML tables sortable without backend shenanigans”

  1. Hi Andy!
    The sortable works really well and very easy to use, saved my life!
    I just notice it also changes the colours of the table (gray). It looks good but it is a bit off from the rest of my web. Is it possible to keep the colours as they are somehow?

  2. I commented out the following in the sortable.css file and it works like a charm 🙂

    /* .sortable {
    –stripe-color: #e4e4e4;
    –th-color: #fff;
    –th-bg: #808080;
    –td-color: #000;
    –td-on-stripe-color: #000;
    border-spacing: 0;
    } */
    /* .sortable tbody tr:nth-child(odd) {
    background-color: var(–stripe-color);
    color: var(–td-on-stripe-color);
    } */
    /* .sortable th {
    background: var(–th-bg);
    color: var(–th-color);
    font-weight: normal;
    text-align: left;
    text-transform: capitalize;
    vertical-align: baseline;
    white-space: nowrap;
    } */
    /* .sortable td {
    color: var(–td-color);
    } */

    Thanks so much Andy for this, I wouldn’t have been able to have this functionality if I had to write it myself… to newbie for that haha

Leave a Reply