Take the 2-minute tour ×

So I've got a list of hidden fields:

<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[0]" value=foo /></li>
    <li>Bar<input class="hiddenThing" type=hidden name="thing[1]" value=bar /></li>
    <li>Baz<input class="hiddenThing" type=hidden name="thing[2]" value=baz /></li>

Purely informational, I don't expect this to be related to the answer, but FYI I'm using the JQuery UI "sortable" plugin:

<script type="text/javascript">
$(document).ready(function () {
    $('ul.reorderable').sortable({ update: stuffHappens; });

The thing you need to understand from this is that the sortable plugin allows the user to reorder these elements arbitrarily. Now, what I want to do is implement a revert button.

<button value="Revert" onClick="revertList()" />

I want this to put the elements of the list back in order based on the name of the hidden inputs. I imagine this will require regexes (to extract the number from the brackets in the name. thing[10] should come after thing[9]) and I imagine that JQuery will be handy. But I'm drawing a blank when I try to approach this problem, probably because I'm not familiar with sorting DOM elements nor regexing with JavaScript.

Keeping this naming format is a must.

share|improve this question

3 Answers 3

up vote 1 down vote accepted

I'd probably use a standard array sort, then remove all the items and add them back sorted:

$('#reorder').click(function() {
    // get the list items and store references to them,
    // grabbing their names on the way
    var items = [];
    $('ul.reorderable li').each(function() {
        var name = $('input', this).attr('name'),
            // regex is overkill if you're always using the same format
            // this is quick, but a little hacky - parseInt stops
            // at non-numeric characters
            pos = parseInt(name.split("[")[1]);
            item: this, // store a reference to the DOM element
            pos: pos 
    // now sort by name
    items.sort(function(a,b) {
        return a.pos > b.pos ? 1 : -1;
    // delete the items and add them back sorted
    var $ul = $('ul.reorderable');
    // forEach() might be more elegant, but isn't cross-browser yet
    for (var x=0; x<items.length; x++) {

Working version here: http://jsfiddle.net/nrabinowitz/Ew2EX/3/

This might get slow if you have a large number of items, but it's much easier than trying to reorder them in-place.

Code updated to compare single- and double-digit numbers (because "2" > "11").

share|improve this answer
pretty good, but the string comparison doesn't capture the numeric sort I need for lists > 10. Forked example: jsfiddle.net/wWmA9 –  Dan Burton May 19 '11 at 20:31
Yep, just worked that out. Updated code coming momentarily. –  nrabinowitz May 19 '11 at 20:32
Works like a charm. I ended up using a slightly different approach but using most of the same concepts from your solution, including the hacky parseInt(name.split("[")[1]) which I thought was clever. –  Dan Burton May 19 '11 at 22:25
function revertList() {
    var $ul = $('ul.reorderable'),
        $inps = $ul.find('li').find('input.hiddenThing');

    for (var i = 0, il = $inps.length; i < il; i++) {

Demo →

share|improve this answer
I like that approach, but it only works if you're certain to have the exact series - stick an extra thing[22] in and it'll break. Not sure whether the OP's use case includes this concern or not. –  nrabinowitz May 19 '11 at 20:41
I was about to note the same thing. In fact, my particular use case does not include that concern; the <li>s are auto-generated and therefore the hidden element names are always sequential from 0 up. –  Dan Burton May 19 '11 at 20:46
Here's a version of @mVChr's response that works with non-sequential indexes: jsfiddle.net/nrabinowitz/Ew2EX/6 . I'd go with his answer - more elegant than mine for your use case. –  nrabinowitz May 19 '11 at 22:05
despite nrabinowitz's suggestion, I've accepted his answer. But +1 for this beautiful jquery-centric answer. –  Dan Burton May 19 '11 at 22:28

I know this is an old thread, but it's actually very simple to sort elements once you have selected them with jQuery.

Being array-based, you can apply sorting to it using the standard Array.prototype.sort() method. Once the child elements have been sorted, you can append them back into the parent element without having to worry about duplicating elements; it would just work :)

To get the numeric index out of the name I've opted to simply filter out anything that's not a digit.

$('.reorderable').append(function() {
  return $(this).children().sort(function(a, b) {
    var re = /\d+/,
        a_index = +a.name.match(re)[0],
        b_index = +b.name.match(re)[1];
    return a_index - b_index;
<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[2]" value=foo /></li>
    <li>Baz<input class="hiddenThing" type=hidden name="thing[0]" value=baz /></li>

share|improve this answer

Your Answer


