Description
Table rows must be swapped at arbitrary positions in the table, i.e. row i and row j must change positions, where i and j are not necessarily adjacent. See current implementation below. Table rows should be sorted by column; a column is specified by sort_index which is generated by pressing one of the table headers.
The problem with the implementation is that the table is sorted incrementally by each click of a header, while it should be sorted by a single click.
var table_index = {
    watched: 0,
    title: 1,
    director: 2,
    year: 3
};
var sort_index = 0;
$(document).ready(function()
{
    var table_headers = document.getElementById("header-item").children;
    for (var k = 0; k < table_headers.length; k++)
    {
        $("#" + table_headers[k].id).bind("click", function(e)
        {
            sort_index = table_index[e.target.id];
            var table = document.getElementById("film-list");
            for (var i = 1; i < table.rows.length - 1; i++)
            {
                var a = table.rows[i].getElementsByTagName("td")[sort_index].innerHTML;
                for (var j = i + 1; j < table.rows.length; j++)
                {
                    var b = table.rows[j].getElementsByTagName("td")[sort_index].innerHTML;
                    var swap = 0;
                    switch (sort_index)
                    {
                    // Alphabetic sort
                    case 0:
                    case 1:
                    case 2:
                        if (b.toLowerCase() < a.toLowerCase())
                            swap = 1;
                        break;
                    // Numeric sort
                    case 3:
                        if (b - a < 0)
                            swap = 1;
                        break;
                    }
                    if (swap == 1)
                    {
                        $(".row-item").eq(i - 1).after(table.rows[j]);
                        $(".row-item").eq(j - 1).after(table.rows[i]);
                    }
                }
            }
        });
    }
});
Edit
It appears the real problem was related to closures inside loops. When a header is clicked, only the last table-row swap is actually updated in DOM, and as such multiple clicks are needed to sort the table properly.
I will post my own solution to this, to clarify the real problem.