Search code examples
javascripthtmltogglesortedlist

Order an HTML list and then target elements


I am working on a function to order a HTML list. I've found the following code on StackOverflow (thx!!) and I tweaked a little bit. My goal is to sort the list and then, once sorted, display the undisplayed (!(":visible")) lis elements. The function works perfectly without the particular part made for displaying the undisplayed elements.

function sortList(ul){ 
var new_ul = ul.cloneNode(false);

// Add all lis to an array
var lis = []; 
for(var i = ul.childNodes.length; i--;){
if(ul.childNodes[i].nodeName === 'LI')
lis.push(ul.childNodes[i]); 
} 

// Sort the lis in descending order
lis.sort(function(a, b){
return parseInt(b.getElementsByClassName(variable)[0].innerHTML , 10) - parseInt(a. getElementsByClassName(variable)[0].innerHTML , 10); 
});
if (order == 'asc') {lis.reverse();}

// Add them into the ul in order 
for(var i = 0; i < lis.length; i++) {
//THIS IS THE PART that makes the function not working anymore
    if (!lis[i].is(":visible")) {
        lis[i].fadeToggle("slow","linear");
    }
//END OF THE PART
    new_ul.appendChild(lis[i]);
}
ul.parentNode.replaceChild(new_ul, ul); 
}

I call the function like this : sortList(document.getElementsByClassName('list')[0],'date','asc');

My HTML looks like this:

<ul class="list">
    <li> <span class="date">1</span></li>
    <li> <span class="date">2</span></li>
    <li style="display:none;"> <span class="date">3</span></li>
    <li style="display:none;" > <span class="date">4</span></li>
</ul>

Thanks for you help !


Solution

  • If you are going to use jQuery for the toggle functions you need to include it in your page

    Also, your sortList function did not pass the other parameters down so, I changed it to this

    function sortList(ul, variable, order) { // <-- pass the parameters here
        var new_ul = ul.cloneNode(false);
    
        // Add all lis to an array
        var lis = [];
        for (var i = ul.childNodes.length; i--;) {
            if (ul.childNodes[i].nodeName === 'LI') lis.push(ul.childNodes[i]);
        }
    
        // Sort the lis in descending order
        lis.sort(function (a, b) {
            return parseInt(b.getElementsByClassName(variable)[0].innerHTML, 10) - parseInt(a.getElementsByClassName(variable)[0].innerHTML, 10);
        });
        if (order == 'asc') {
            lis.reverse();
        }
    
        // Add them into the ul in order 
        for (var i = 0; i < lis.length; i++) {
            //THIS IS THE PART that makes the function not working anymore
            /* using jQuery notation for the jQuery function calls */
            if (!$(lis[i]).is(":visible")) {  // <-- here
                $(lis[i]).fadeToggle("slow", "linear"); // <-- and here
            }
            //END OF THE PART
            new_ul.appendChild(lis[i]);
        }
        ul.parentNode.replaceChild(new_ul, ul);
    }
    

    DEMO JS FIDDLE

    Lastly, if you are using jQuery, you can replace all your getElementsByClassName(..) with a simple $('.className') as it is basically the same thing (i.e. that's the jQuery syntax to accomplish the same selection)