indra-uolles
indra-uolles

Reputation: 31

Using jQuery appendTo() while sorting html elements

I need to effectively sort html nodes inside some container. Here's a simplified version of what I did:

<html>
<ul class="navigation">
    <li class="first">Main</li>
    <li class="second">HTML и CSS tricks</li>
    <li class="third">Study</li>
    <li class="fourth">HTML reference</li>
</ul>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
var rows = $( ".navigation" ).children();

function sortAlpha(a,b){  
    return a.innerHTML.toLowerCase() > b.innerHTML.toLowerCase() ? 1 : -1;  
};  

rows.sort(sortAlpha).appendTo('.navigation'); 
</script>
</html>

Some of the people I work with are suspicious about the line

rows.sort(sortAlpha).appendTo('.navigation'); 

They ask is it ok to use appendTo this way, maybe there are (or will be in the future) some drawbacks of using this method, how come using appendTo replaces the content of the parent container and why it won't just add the sorted things to the parent container? What if it's a temporary feature of jQuery and it won't work like that in the future?

I need to say that the real case is more complex, e.g. we use the library that allows us to have object-oriented programming at the front-end side, also each element which needs to be sorted is a row of a table that contains some controls that have event bindings.

The idea was to replace the content of the dom node with sorted elements so this library wouldn't notice that. I used the approach described above in the real code and it's bugless at least for now, but the question remains: 1) what are the drawbacks of this approach, 2) what can be a better option?

Upvotes: 2

Views: 1352

Answers (4)

Rahul Kumar
Rahul Kumar

Reputation: 524

Try this,

$(function() {
$.fn.sortList = function() {
var mylist = $(this);
var listitems = $('li', mylist).get();
listitems.sort(function(a, b) {
    var compA = $(a).text().toUpperCase();
    var compB = $(b).text().toUpperCase();
    return (compA < compB) ? -1 : 1;
});
$.each(listitems, function(i, itm) {
    mylist.append(itm);
});
 }

$("ul.navigation").sortList();

});

Demo

Upvotes: 0

enguerranws
enguerranws

Reputation: 8233

Basically, appendTo() will insert html nodes at the end of the specified element, here : .navigation

Assuming you're using jQuery Sort plugin (http://github.com/jamespadolsey/jQuery-Plugins/tree/master/sort/), if you need to reorder your navigation menu, you could simply do :

$('.navigation li').sort(function(a, b){
  return $(a).text() > $(b).text() ? 1 : -1;
});

By the way, if you want to replace the full content of an element, consider html() method, which empty the node and insert the content.

Upvotes: 0

Nick Manning
Nick Manning

Reputation: 2989

appendTo is supposed to appendTo...I'm surprised it just acts like .html(). To make them happy why dont you just do $('.navigation').empty().append(rows.sort(sortAlpha));

Upvotes: 0

Anthony Grist
Anthony Grist

Reputation: 38345

This is covered in the documentation for .appendTo():

We can also select an element on the page and insert it into another:

$( "h2" ).appendTo( $( ".container" ) );

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned)...

So, since you're selecting elements that already exist on the page, and calling .appendTo() with a selector that only matches a single element, those selected elements are moved into that new target element, in the order they're in inside of your set of matched elements. It's irrelevant that you're putting them back into the same element.

What are the drawbacks?

None that I can think of. You're using a documented aspect of what the function does. It's unlikely that the way that .appendTo() works is ever going to be changed.

Upvotes: 1

Related Questions