Page 1 of 1

Javascript Sorter for HTML lists

Posted: Thu Jan 22, 2009 8:50 pm
by nor0101
The problem description:

Write a function in Javascript to sort <li>'s lexicographically on the linked text they contain. It came up for a client using Serena Collage (R.I.P.) for content management. Long story short, they need their autogenerated subnavigation links to be alphabetized and doing it on the server side was not an option due to their environment.

My solution works fine in Firefox, Safari, IE6, & IE7, but basically I'm posting this because I'm inexperienced doing anything but really simple DOM stuff in Javascript and am hoping someone will come along school me to how I should have approached it. :?

My solution:

See it in action at: http://oneorangesoftware.com/connor/misc/sorter.html

Code: Select all

 
            function sortUL(listName) {
                var targetList = document.getElementById(listName);
                var listItems = targetList.childNodes;
                // remove extraneous array elements
                var tempArr = Array();
                var i;
                for (i=0; i<listItems.length; i++) {
                    if (listItems[i].innerHTML != null) {
                        var ndx = tempArr.length;
                        tempArr[ndx] = listItems[i];
                    }
                }
                listItems = tempArr;
                listItems.sort(function sortListItemsBy(item1, item2) {
                    var item1Text, item2Text, j;
                    for (j=0; j<item1.childNodes.length; j++) {
                        if (item1.childNodes[j].innerHTML != null) {
                            item1Text = item1.childNodes[j].innerHTML;
                            break;
                        }
                    }
                    for (j=0; j<item2.childNodes.length; j++) {
                        if (item2.childNodes[j].innerHTML != null) {
                            item2Text = item2.childNodes[j].innerHTML;
                            break;
                        }
                    }
                    if (item1Text > item2Text)
                        return 1;
                    else
                        return -1;
                });
                var newListHTML = "";
                for (i=0; i<listItems.length; i++) {
                    newListHTML = newListHTML+"<li>"+listItems[i].innerHTML+"<\/li>";
                }
                targetList.innerHTML = newListHTML;
            }
 
Any comments would be greatly appreaciated, thanks for reading!

Re: Javascript Sorter for HTML lists

Posted: Sun Jan 25, 2009 12:49 pm
by kaszu
What I don't like is that your function is replacing list innerHTML, which is bad because all attached events will be lost (and probably will be slower too). Instead change list item order.
How I would do it:

Code: Select all

 
function sortUL(listName) {
    var targetList = document.getElementById(listName);
    var tempArr = [];
    
    for(var i=0,j=targetList.childNodes.length; i<j; i++) {
        if (targetList.childNodes[i].nodeType == 1) { //Check that it's an html element
            tempArr.push({
                value: targetList.childNodes[i].getElementsByTagName('A')[0].innerHTML, //save value for .sort function
                item: targetList.childNodes[i] //save reference to the list item
            });
        }
    }
    
    //Sort tempArr
    tempArr.sort(function (a, b) {
        return (a.value > b.value ? 1 : -1);
    });
    
    //Change list item order by pushing each to the end of the list
    for(var i=0,j=tempArr.length; i<j; i++) {
        targetList.appendChild(tempArr[i].item);
    }
}

Re: Javascript Sorter for HTML lists

Posted: Sun Jan 25, 2009 10:46 pm
by nor0101
Hey, thanks kaszu!

That is certainly more robust. It's embarrassing but I just learned about JS object literals yesterday while reading some code.