I have this list :
<ul>
<li id="6">
list 6: somethings
</li>
<li id="2">
list 2: somethings
</li>
<li id="4">
list 4: somethings
</li>
<li id="5">
list 5: somethings
</li>
<li id="0">
list 0: somethings
</li>
</ul>
and I'd like (with Javascript/jQuery) order these elements by the id (ASC) keeping the event handler for each element.
Is it possible? How can I do it?
I have this list :
<ul>
<li id="6">
list 6: somethings
</li>
<li id="2">
list 2: somethings
</li>
<li id="4">
list 4: somethings
</li>
<li id="5">
list 5: somethings
</li>
<li id="0">
list 0: somethings
</li>
</ul>
and I'd like (with Javascript/jQuery) order these elements by the id (ASC) keeping the event handler for each element.
Is it possible? How can I do it?
Share Improve this question edited Jun 22, 2011 at 7:29 Jonathan Hall 79.9k19 gold badges159 silver badges203 bronze badges asked Jun 22, 2011 at 7:22 markzzzmarkzzz 48.1k126 gold badges319 silver badges534 bronze badges 5- The event handlers won't be detached, but your notion of ordering is wrong, because you can't have an integer ID attribute, neither can one start with an integer. – Shef Commented Jun 22, 2011 at 7:27
- ? I mean the ID for each <li> – markzzz Commented Jun 22, 2011 at 7:32
- Yes, that's what I mean, too. You can't have an integer as the ID of the element. It's not valid. – Shef Commented Jun 22, 2011 at 7:36
-
1
@Shef - That's not the case for HTML5. The only rules are that an
id
must be unique in the document, contain at least one character, and contain no spaces: w3/TR/html5/elements.html#the-id-attribute – James Allardice Commented Jun 22, 2011 at 7:41 - Is not so important if it evalutates number as string instead of integer :) – markzzz Commented Jun 22, 2011 at 7:42
4 Answers
Reset to default 6You could just assign the ID's into an array and use sort()
:
var a = [];
$("ul li").attr('id',function(i,e){
a.push(e);
});
$.each(a.sort(),function(i,e){
$("#"+e).appendTo('ul');
});
You are never removing them from the list, just moving them around. Click handler stays intact:
http://jsfiddle/niklasvh/nVLqR/
This should work fine. Using detach
preserves any events associated with the element. You then use a custom sort function to pare the id
attributes of each li
element.
var ul = $("ul");
var li = ul.children("li");
li.detach().sort(function(a, b) {
var pA = $(a).prop("id");
var pB = $(b).prop("id");
return (pA < pB) ? -1 : (pA > pB) ? 1 : 0;
});
ul.append(li);
See an example fiddle here. A click event is attached to the li
with ID "6". After the list has been reordered, that click event is still handled.
I think to order them you'll had to remove and add them back into the DOM... and therefore you'll certainly lose the event handler. Are you in control of the handler, can you rebind or use live()
instead?
The alternative would be to absolutely position the li
elements and use the css position properties (top
, right
, bottom
, left
) to move them around, this will keep them in the same order in the DOM, but render them in your desired order.t
This example work for me:
var mylist = $('.item').detach().sort(function (a, b) {
return $(a).find(selector).html() > $(b).find(selector).html();
});
$("#container").html(mylist);
or if you want to sort with other informations:
var mylist = $('.item').detach().sort(function (a, b) {
return $(a).find(selector).attr('data-title')() > $(b).find(selector).attr('data-title');
});
$("#container").html(mylist);