Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery incorrectly sort <li> by id

I have this <li> to sort by id:

<ul id="members-list">
   <li id="member_8">
   <li id="member_4">
   <li id="member_7">
   <li id="member_12">
   <li id="member_11">
   <li id="member_13">
   <li id="member_5">
   <li id="member_6">
   <li id="member_9">
   <li id="member_3">
   <li id="member_2">
   <li id="member_1">
   <li id="member_10">
</ul>

The code I use:

<script>
$( document ).ready(function() {
    $("li[id*='member_']").sort(function (a, b) {
        return parseInt(a.id.replace('member_', '')) > parseInt(b.id.replace('member_', ''));
    }).each(function () {
        var elem = $(this);
        elem.remove();
        $(elem).appendTo("ul#members-list");
    });
});
</script>

The result is:

<ul id="members-list">
   <li id="member_5">
   <li id="member_8">
   <li id="member_7">
   <li id="member_1">
   <li id="member_2">
   <li id="member_3">
   <li id="member_4">
   <li id="member_6">
   <li id="member_9">
   <li id="member_10">
   <li id="member_11">
   <li id="member_12">
   <li id="member_13">
</ul>

The <li> are no not sorted correctly, what can cause the problem?

like image 484
Aminesrine Avatar asked Dec 16 '14 09:12

Aminesrine


2 Answers

The problem is that you did not implement the sort function correctly. The function is supposed to return a positive number, negative number or zero; you're returning true/false.

So when a.id is less than/equal to b.id the function returns false which is zero-ish; which is treated as a.id is equal to b.id; this puts the sorting function off the track.

Solution is to change this:

return parseInt(a.id.replace('member_', '')) > parseInt(b.id.replace('member_', ''));

To this:

return parseInt(a.id.replace('member_', '')) - parseInt(b.id.replace('member_', ''));

Having said all that, you could rewrite your code using detach and a single appendTo like this:

$("li[id*='member_']").detach().sort(function(a, b) {
    return +a.id.replace("member_", "") - b.id.replace("member_", "");
}).appendTo("ul#members-list");
like image 92
Salman A Avatar answered Nov 09 '22 23:11

Salman A


assuming you don't have the same number twice, you can use this:

return (parseInt(a.id.replace('member_', '')) > parseInt(b.id.replace('member_', ''))) ? 1 : -1;

Salman A answer works for all cases.

sort() expects the values 1,0,-1 as a return value: Array.prototype.sort(), so you shouldn't use the > sign.

like image 3
Yoni Dabush Avatar answered Nov 09 '22 23:11

Yoni Dabush