defaultNINJA defaultNINJA - 1 month ago 12
Javascript Question

jQuery Exact Number Match For Table Sort

I'm building a jQuery table sorting script. Yes, yes, I know there are plug-ins for that, but where's the fun in ridding someone else's coat tails (not to mention an entire lack of learning and understanding)?

So I've got a good sort going on for alpha types, I'm now working on a numeric sort.

So quick down and dirty. I get the column values and push them into an array:

var counter = $(".sort tr td:nth-child("+(columnIndex+1)+")").length;

for (i = 1; i <= counter; i++) {
columnValues.push($(".sort tr:eq("+i+") td:eq("+columnIndex+")").text());
}


I then sort they array:

columnValues.sort(function(a,b){
return a-b
});


I then check for unique entries (this was mainly for same names):

$.each(columnValues, function(i, el){
if($.inArray(el, uniqueColumns) === -1) uniqueColumns.push(el);
});


I then use the array as a list of keys to get the data from the table and push into another array. This is where the problem comes in. For names it works just fine, but with number (i.e. 3, 30, 36) it doesn't. With the sorted list starting with 3 it sees the 3 in the 30 and/or 36 and grabs it.

Here is what I have tried:

for (i = 0; i < counter; i++) {
var key = uniqueColumns[i];

$(".sort tr:contains("+key+") td").each(function(){
rowValues.push($(this).text());
});

}


And:

for (i = 0; i < counter; i++) {
var key = uniqueColumns[i];

$(".sort tr td").filter(function(i){
if($(this).text() === key) {
rowValues.push($(this).text());
}
});
}


Here is the fiddle running the code with the first set of code (which works better then the second):

UPDATE:

Also just tried this (still not working, works for initial sort but not subsequent):

for (i = 0; i < counter; i++) {
var key = uniqueColumns[i];
var found = false;

$(".sort tr:contains("+key+")").filter(function(j){
$(this).children().each(function(){
if ($(this).text() === key) {
found = true;
}
});

$(this).children().each(function(){
if (found) {
rowValues.push($(this).text());
}
});
});
}

Answer

Figured it out on my own. Decided on a completely different approach. I created a multidimensional array out of the table data, then created a custom sort function that works for both numeric and alpha data. Here is the function that gets the data, sorts the data, and rewrites the table.

function sort(column) {
    var columnIndex = $(column).index(),
    rowValues = [];

    /* Get Data */
    $(".sort tr").not(":first-child").each(function () {
        var innerArray = [];

        $(this).find('td').each(function () {
            innerArray.push($(this).text());
        });

        rowValues.push(innerArray);
    });

    /* Sort Data */
    rowValues.sort((function(index){
        return function(a, b){                
            if (!isNaN(a[index])) {
                a[index] = parseInt(a[index]);
            }

            if (!isNaN(b[index])) {
                b[index] = parseInt(b[index]);
            }

            return (a[index] === b[index] ? 0 : 
                   (a[index] < b[index] ? -1 : 1));
        };
    })(columnIndex));

    /* Replace Data */
    $(".sort tr").not(":first-child").each(function(i){
        $(this).find("td").each(function(j){
            $(this).replaceWith("<td>"+rowValues[i][j]+"</td>");
        });
    });
}