开发者

JavaScript order DOM elements based on name

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>
</ul>

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; });
}
</script>

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.

开发者_如何学JAVA
<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.


function revertList() {
    var $ul = $('ul.reorderable'),
        $inps = $ul.find('li').find('input.hiddenThing');

    for (var i = 0, il = $inps.length; i < il; i++) {
        $inps.filter('[name="thing['+i+']"]').closest('li')
             .detach().appendTo($ul);
    }
}

Demo →


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]);
        items.push({
            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');
    $ul.empty();
    // forEach() might be more elegant, but isn't cross-browser yet
    for (var x=0; x<items.length; x++) {
        $ul.append(items[x].item);
    }
});

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").


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;
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[2]" 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[0]" value=baz /></li>
</ul>

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜