duc duc - 1 month ago 11
Javascript Question

Sorting keep shifting rows when there's 11+ rows

See code in jsfiddle links provided below

There's a bunch of ways to sort a table using javascript (+jquery) out there. I started using James Padolsey's jquery sort plugin. I had to modified his demo code since it did not check for equality (it was only checking greater and less than).

Everything works fine until there's 11+ rows in the table and 3 of the row are the same. The 3 rows kept shifting after each sort. You can try it out here; keep clicking on "Fruit" and notice the "apple" rows are shifting. If you remove one of the table row, the shifting stop and the sort is correct.

I started to see if I can write my own sort and use the js array sort and I ran into the same problem. You can play with it here. Notice that I am sorting by first column only and in ascending every time when you click a table header. Ascending every time and it is still shifting the "apple" rows.

It appears that this is a Javascript array sort issue (since James' plugin is using it too)? Any one have any idea on this or am I doing it wrong?


duc duc
Answer

I ended it up sorting the other columns if the current data I'm sorting is equal. I also decided to mod James' demo code to support this (not his plugin code). http://jsfiddle.net/C8nQ2/1/

The below recursive function support more than 2 columns table. It will go through the column to sort, if it equals, it continue to the next column, etc.

function calc(a, b, first) {
    var valueA = $(a).text(),
        valueB = $(b).text();

    if(valueA == valueB) {
        // 1st time calling & sort is not on 1st column so sort the first by column
        if(first && (index != 0)) {
            return calc(a.parent().children().eq(0), b.parent().children().eq(0));
        }

        // no more columns to sort, both rows are exactly the same
        if(a.index() == th.length - 1) { 
            return 0; 
        }

        // sort by the next column
        return calc(a.next(), b.next());
    } else {
        return (isNaN(valueA) || isNaN(valueB) ? valueA > valueB : +valueA > +valueB) ? inverse ? -1 : 1 : inverse ? 1 : -1;
    }
}
Comments