简体   繁体   中英

jQuery, ordering rows in a table using numbers in child elements

I need to sort the rows in a table using the number in an anchor (anchor that not exist in some rows). Table example:

<table id="sortedtable" class="full">
    <tbody>
        <tr>
            <th>Main tr</th>
        </tr>
        <tr>
            <td>
                <div style="float: left;">Title</div>
                <a class="unreadcount" href="#">7</a>
            </td>
        </tr>
        <tr>
            <td>
                <div style="float: left;">No anchor here :(</div>
            </td>
        </tr>
        <tr>
            <td>
                <div style="float: left;">Javascripthatesme</div>
                <a class="unreadcount" href="#">15</a>
            </td>
        </tr>
        <tr>
            <td>
                <div style="float: left;">Yourox</div>
                <a class="unreadcount" href="#">2</a>
            </td>
        </tr>
        <tr>
            <td>
                <div style="float: left;">This has more than one word and no anchor</div>
            </td>
        </tr>
        <tr>
            <td>
                <div style="float: left;">Title</div>
                <a class="unreadcount" href="#">11</a>
            </td>
        </tr>
        <tr>
            <td>
                <div style="float: left;">Big Bang Theory is not funny</div>
                <a class="unreadcount" href="#">4</a>
            </td>
        </tr>   
    </tbody>
</table>

Using the solution in this question I was able to make a semi-working code:

var $table = $('table');

var rows = $table.find('tr').get();
rows.sort(function(a, b) {
    var keyA = $(a).find('a.unreadcount').text();
    var keyB = $(b).find('a.unreadcount').text();
    if (keyA < keyB) return 1;
    if (keyA > keyB) return -1;
    return 0;
});
$.each(rows, function(index, row) {
    $table.children('tbody').append(row);
});

You can see it working in this jsFiddle . The problem and where I need help is the way numbers are sorted (8 come first than 32 or 12, for example) and that I need to ignore the first row (where "Main tr" is) and leave it always at the top.

And as an extra, if you could give me the direction to make a button that put the table in the original order again would be awesome.

Thanks.

You need to convert the text values to numbers for a proper numeric sort. The easies way to convert is with the unary plus operator .

To leave the heading row in place just don't include that in the array you sort, which is easy enough using jQuery's .slice() method .

To add a button that restores the table to its original order just keep a copy of the array before you sort it, which I've done with the standard Array .slice() method .

So:

var $table = $('table');

var originalRows = $table.find('tr').slice(1).get(),
    rows = originalRows.slice(0);
rows.sort(function(a, b) {
    var keyA = +$(a).find('a.unreadcount').text();
    var keyB = +$(b).find('a.unreadcount').text();
    if (keyA < keyB) return 1;
    if (keyA > keyB) return -1;
    return 0;
});
$.each(rows, function(index, row) {
    $table.children('tbody').append(row);
});

// button that changes it back:
$("input").click(function(){
    $.each(originalRows, function(index, row) {
       $table.children('tbody').append(row);
    });
});
​

Demo: http://jsfiddle.net/hLvwz/5/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM