And you never thought that algorithm class from college was going to pay off. In this post I'll be going over how to add the ability to sort to any table in JavaScript. All you will need to do is to add the sorting class to the specified table that you wish to add sorting to and then watch the magic happen.

For this particular example, I used the bubble sort algorithm, because it is one of the simplest to implement and to show. However, it is not the most efficient as far as performance goes. So feel free to implement your own sorting algorithms.

Number City
7 Los Angeles
4 Chicago
6 San Francisco
2 Long Beach

1. Create sort links

First off, let's start by creating the sorting links to each header cell in our tables. And we can do that once the page loads. The following function will generate sorting links for each table with the 'sorting' class.


        var tables = document.querySelectorAll('.sorting');

        function loadsort()
        {
            for (var i = 0; i < tables.length; i++)
            {
                var headers = tables[i].querySelectorAll('th');

                for (var x = 0; x < headers.length; x++)
                {
                    var header = headers[x];
                    var sortlink = document.createElement('a');
                    var datatype = header.dataset.type;

                    sortlink.innerHTML = header.innerHTML + ' ▴';
                    sortlink.dataset.column = x;
                    sortlink.dataset.name = header.innerHTML;
                    sortlink.dataset.direction = 'asc';
                    sortlink.addEventListener('click', function (e) {
                        sort(this);
                    });

                    headers[x].innerHTML = '';
                    headers[x].appendChild(sortlink);
                }
            }
        }

We're essentially creating new links and replacing our header text with them. Once you click on the link, the appropriate sorting function will be called. Notice the dataset values that are being added to the sorting link. The direction dataset attribute will determine our initial sorting direction on our table, whether ascending or descending.

2. Create your sort function

There are numerous sorting algorithms at your disposal, and rather than listing them all down or defining each one, I'll select the simplest to use as an example. And that would be the infamous Bubble sort. Easy to implement, but not the best when it comes to performance. So feel free to replace it with your sorting algorithm of choice.


        function sort(el)
        {
            var direction = el.dataset.direction;
            var column = el.dataset.column;

            var table = getTableFromChild(el);
            var rows = table.rows;

            for (var x = 0; x < rows.length; x++)
            {
                var changes = false;

                for (var i = 1; i < rows.length-1; i++)
                {
                    var row = rows[i];
                    var otherrow = rows[i + 1];
                    var parent = row.parentNode;

                    var value = rows[i].cells[column].innerHTML;
                    var next = rows[i + 1].cells[column].innerHTML;

                    if (value > next && direction == 'asc') {
                        changes = true;
                        parent.insertBefore(otherrow, row);
                    }

                    else if (value < next && direction == 'desc')
                    {
                        changes = true;
                        parent.insertBefore(otherrow, row);
                    }
                }

                if (changes == false)
                    break;
            }

            el.dataset.direction = direction == 'asc' ? 'desc' : 'asc';
            el.innerHTML = el.dataset.name + (direction == 'asc' ? ' ▾' : ' ▴');
        }

Just a quick breakdown of the entire thing. We first retrieve the parent table that the clicked header cell belongs to and then we will traverse through each of the rows in that table. That's when the magic of the bubble sort kicks in. I'll sequentially compare values until the end of the table rows collection. And I will do so until there are no more rows to sort.

Once the rows have been sorted, I will set the new sorting-direction of the header to either ascending or descending, depending on the previous value and I will update dataset direction value to the new direction.

The above sorting function makes use of the following helper function. Because I want this sorting functionality to be as generic as possible across any number of tables on a page, I need to be able to return the parent table element that will be sorted based on the header column clicked, and the following function will return just that.


        function getTableFromChild(child)
        {
            var element = child;
            var type = '';

            while (type.toLowerCase() != 'table')
            {
                element = element.parentNode;

                if (element != null)
                {
                    type = element.nodeName;
                }

                else
                {
                    break;
                }
            }

            return element;
        }

Note that sorting columns with mixed data types will result in random ordering more than likely. So be sure to add this functionality to tables with static data.

Walter Guevara

Walter G. is a software engineer with over 10 years of professional experience. When he isn't blogging or being a CTO he enjoys coding randomly complex things that he hopes many people will get a chance to use one day.

Have a question or comment?

No comments posted yet

Add a comment

Send me your weekly newsletter filled with awesome ideas
Start
Score: 0
snake left
snake up
snake down
snake right