60

Is it possible to reorder <li> elements with JavaScript or pure jQuery. So if I have a silly list like the following:

<ul>
    <li>Foo</li>
    <li>Bar</li>
    <li>Cheese</li>
</ul>

How would I move the list elements around? Like put the list element with Cheese before the list element with Foo or move Foo to after Bar.

Is it possible? If so, how?

Flexo
  • 87,323
  • 22
  • 191
  • 272
Alex
  • 64,178
  • 48
  • 151
  • 180

6 Answers6

97
var ul = $("ul");
var li = ul.children("li");

li.detach().sort();
ul.append(li);

This is a simple example where <li> nodes are sorted by in some default order. I'm calling detach to avoid removing any data/events associated with the li nodes.

You can pass a function to sort, and use a custom comparator to do the sorting as well.

li.detach().sort(function(a, b) {
   // use whatever comparison you want between DOM nodes a and b
});
Anurag
  • 140,337
  • 36
  • 221
  • 257
40

If someone is looking to reorder elements by moving them up/down some list one step at a time...

//element to move
var $el = $(selector);

//move element down one step
if ($el.not(':last-child'))
    $el.next().after($el);

//move element up one step
if ($el.not(':first-child'))
    $el.prev().before($el);

//move element to top
$el.parent().prepend($el);

//move element to end
$el.parent().append($el);
alexg
  • 3,015
  • 3
  • 23
  • 36
11

One of my favorite things about jQuery is how easy it is to write tiny little add-ons so quickly.

Here, we've created a small add-on which takes an array of selectors, and uses it to order the children of the target elements.

// Create the add-on

$.fn.orderChildren = function(order) {
 this.each(function() {
  var el = $(this);
  for(var i = order.length - 1; i >= 0; i--) {
   el.prepend(el.children(order[i]));
  }
 });
 return this;
};


// Call the add-on

$(".user").orderChildren([
 ".phone",
 ".email",
 ".website",
 ".name",
 ".address"
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class="user">
 <li class="name">Sandy</li>
 <li class="phone">(234) 567-7890</li>
 <li class="address">123 Hello World Street</li>
 <li class="email">someone@email.com</li>
 <li class="website">https://google.com</li>
</ul>
<ul class="user">
 <li class="name">Jon</li>
 <li class="phone">(574) 555-8777</li>
 <li class="address">123 Foobar Street</li>
 <li class="email">jon@email.com</li>
 <li class="website">https://apple.com</li>
</ul>
<ul class="user">
 <li class="name">Sarah</li>
 <li class="phone">(432) 555-5477</li>
 <li class="address">123 Javascript Street</li>
 <li class="email">sarah@email.com</li>
 <li class="website">https://microsoft.com</li>
</ul>

The function loops backwards through the array and uses .prepend so that any unselected elements are pushed to the end.

Sandy Gifford
  • 7,219
  • 3
  • 35
  • 65
6

Here is a jQuery plugin to aid with this functionality: http://tinysort.sjeiti.com/

dennismonsewicz
  • 25,132
  • 33
  • 116
  • 189
4

something like this?

​var li = $('ul li').map(function(){
              return this;
         })​.get();
$('ul').html(li.sort());

demo

I was somewhat lost you may be wanting something like this...

$('ul#list li:first').appendTo('ul#list'); // make the first to be last...
$('ul#list li:first').after('ul#list li:eq(1)'); // make first as 2nd...
$('ul#list li:contains(Foo)').appendTo('ul#list'); // make the li that has Foo to be last...

more of it here1 and here2

Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
  • this line doesnt seem to work `$('ul#list li:first').after('ul#list li:eq(1)');` – t q Dec 30 '12 at 18:59
3

Have a look at jquery ui sortable

http://jqueryui.com/demos/sortable/

Karl Johan
  • 4,012
  • 1
  • 25
  • 36
  • While very cool, I don't need the user to be able to resort, I just want to know if I can do it programmatically, either using jQuery or just javascript. – Alex Jun 16 '10 at 05:09
  • Aah I see! Didn't really get that from your question – Karl Johan Jun 16 '10 at 06:42