mrdaliri
mrdaliri

Reputation: 7358

sort table by price column

It's the billing list:

Service   Price
---------------
S1        13 CHF
S2        Free
S3        Free
S4        40 CHF

I want to sort it by price using jQuery or pure JavaScript. (not server-side)

I tried jQuery Tablesorter, but it failed. Because some prices aren't number. (Free)

What can I do? Can Tablesorter support it? Or I should use other plugins...

Upvotes: 1

Views: 3504

Answers (5)

jfriend00
jfriend00

Reputation: 707976

Because you have custom, non-numeric values to sort, you will need some sort of custom sort function. Here's such a custom sort routine for your table:

HTML:

<table id="service">
    <tr><td class="sortBy" data-sortType="findNumber">Service</td><td class="sortBy" data-sortType="numeric">Price</td></tr>
    <tr><td>S1</td><td>13 CHF</td></tr>
    <tr><td>S2</td><td>Free</td></tr>
    <tr><td>S3</td><td>Free</td></tr>
    <tr><td>S4</td><td>40 CHF</td></tr>
</table>

Code:

$(".sortBy").click(function() {
    var self = $(this);
    var tbody = self.closest("tbody");

    // determine which column was clicked on
    var column = self.index();

    // get the sort type for this column
    var sortType = self.data("sortType");
    var sortCells = [];

    // get all rows other than the clicked on row
    //    find the right column in that row and
    //    get the sort key from it
    $(this).closest("tr").siblings().each(function() {
        var item = $(this).find("td").eq(column);
        var val = item.text();
        var matches;
        if (sortType == "numeric") {
            if (val.toLowerCase() == "free") {
                val = 0;
            } else {
                val = parseInt(val, 10);
            }
        } else {
            // find numbers in the cell
            matches = val.match(/\d+/);
            if (matches) {
                val = parseInt(matches[0], 10);
            } else {
                val = 0;
            }
        }
        sortCells.push({cell: item, data: val});
    });
    // sort by the key
    sortCells.sort(function(a, b) {
        return(a.data - b.data);
    });
    // reinsert into the table in sorted order
    for (var i = 0; i < sortCells.length; i++) {
        sortCells[i].cell.parent().appendTo(tbody);
    }
});

Working demo: http://jsfiddle.net/jfriend00/3w9gQ/

Upvotes: 0

Pavlo Shandro
Pavlo Shandro

Reputation: 808

If you don't want to use heavy plugins, you cant to sort it manually:

$(function(){
    var table=$('#table');
    var rowsArray=$('tr',table).sort(function(current,next){
        var compareCurrent=$('td.price',current).text().toUpperCase();
        var compareNext=$('td.price',next).text().toUpperCase();
        return (compareCurrent<compareNext)? -1 : (compareCurrent > compareNext) ? 1 : 0;
    });
    $('tr',table).remove();
    $.each(rowsArray,function(index,element){
        $(element).appendTo(table)
    })
})

In this example you should add class "price" to cells with prices. Or you can use pseudo-selector ":last-child".

Upvotes: 1

Aust
Aust

Reputation: 11622

Here is some custom sort code that will work for you assuming the following:

  1. Your table has the id of items
  2. Each row (tr) you want sorted have the class item
  3. Each price cell (td) has the class price

Then just include the following jQuery code and call the function when you want to sort: (Here is a demo)

var sorted_by_price = false;

function sortByPrice() {
    $('#items').append(
        $('#items').find('tr.item').sort(function (a, b) {
            var td_a = $($(a).find('td.price')[0]);
            var td_b = $($(b).find('td.price')[0]);
            if(sorted_by_price){
                if(td_a.html() == 'Free') return 1;
                return td_b.html().replace(/\D/g, '') - td_a.html().replace(/\D/g, '');
            }else{
                if(td_a.html() == 'Free') return -1;
                return td_a.html().replace(/\D/g, '') - td_b.html().replace(/\D/g, '');
            }
        })
    );
    if(sorted_by_price) sorted_by_price = false;
    else sorted_by_price = true;
}

Upvotes: 1

David Kiger
David Kiger

Reputation: 1996

You can write your own parser. See the documentation at: http://tablesorter.com/docs/example-parsers.html

Working example:

$.tablesorter.addParser({ 
    id: 'price', 
    is: function(s) { 
        return false; 
    }, 
    format: function(s) { 
        return s.replace(/Free/,0).replace(/ CHF/,""); 
    }, 
    type: 'numeric' 
}); 

$(function() { 
    $("table").tablesorter({ 
        headers: { 
            1: { 
                sorter:'price' 
            } 
        } 
    }); 
});

http://jsfiddle.net/8BCHR/

Upvotes: 0

Pavlo Shandro
Pavlo Shandro

Reputation: 808

You can use DataTables (http://www.datatables.net/). It's very powerful JS plugin.

Upvotes: 0

Related Questions