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>
精彩评论