Search code examples
javascriptjquerysortingin-place

javascript sort of HTML elements in-place


in continuation for javascript sort of HTML elements

I want to sort elements in different <ol>( eventually in <div>) the sort should preferably be in-place and not to unwrap(),sort() and wrap

HTML

<ol class="table" style="display: block; ">
    <li class="menu__run">I</li>
    <li class="menu__run">IXX</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
</ol>
<ol class="table">
    <li class="menu__run">I</li>
    <li class="menu__run">IXX</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__test">st</li>
    <li class="menu__test">st</li>
    <li class="menu__test">st</li>
</ol>

javascript

var sort_by_name = function(a, b) {
    return a.innerHTML.toLowerCase().localeCompare(b.innerHTML.toLowerCase());
}

var list = $(".table > li").get();
list.sort(sort_by_name);
for (var i = 0; i < list.length; i++) {
    list[i].parentNode.appendChild(list[i]);
}​

the result I look for is

<ol class="table" style="display: block; ">
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
</ol>
<ol class="table">
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">I</li>
    <li class="menu__run">IXX</li>
    <li class="menu__run">IXX</li>
    <li class="menu__test">st</li>
    <li class="menu__test">st</li>
    <li class="menu__test">st</li>
</ol>

let a,b be DOM elements, and a appear lower on the list than b (lower is position in the document ) and value(a) > value(b) then a and b will be switched in the document. no matter that a and b may not be siblings.

http://jsfiddle.net/yqd3w/7/


Solution

  • To speed the task up by doing less comparisons, you can do:

    $(".table").each(function(){
        var list = $(this).children().get().sort(sort_by_name);
        for (var i = 0; i < list.length; i++)
            this.appendChild(list[i]);
    }​);
    

    ...although it does not affect the result.


    EDIT: OK, I got you:

    var $t = $(".table");
    var list = $t.children().get().sort(sort_by_name);
    $t.map(function() {
        return {t:this, l:this.childNodes.length};
    }).each(function(i, o) {
        $(o.t).append(list.splice(0, o.l));
    });