Reputation: 49
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.
Upvotes: 2
Views: 652
Reputation: 150040
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/
Upvotes: 5