Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting <li> tags

I have a a and I would like to sort my list alphabetically (I don't want caps to matter) according to a class named "name". How would I do this?

<ul class="column">
  <li>
    <table>
      <tr>
        <td class="name" >Name of Item</td>
      </tr>
      <tr>
        <td>Content</td>
      </tr>
      <tr>
        <td>morecontent</td>
        <td>morecontent</td>
      </tr>
    </table>
  </li>
  <li>
    <table>
      <tr>
        <td class="name" >Another name of item</td>
      </tr>
      <tr>
        <td>Content</td>
      </tr>
      <tr>
        <td>morecontent</td>
        <td>morecontent</td>
      </tr>
    </table>
  </li>
</ul>

Thanks

like image 723
PHPNooblet Avatar asked Sep 30 '09 03:09

PHPNooblet


2 Answers

Using jQuery, this should do it:

function sort() {
    $($('ul.column>li').get().reverse()).each(function(outer) {
        var sorting = this;
        $($('ul.column>li').get().reverse()).each(function(inner) {
            if($('td.name', this).text().localeCompare($('td.name', sorting).text()) > 0) {
                this.parentNode.insertBefore(sorting.parentNode.removeChild(sorting), this);
            }
        });
    });
}

The above is a little dense though, so if you want to understand what's going on, let's break it down line-by-line:

function sort() {

    //get each <li> which is a child of <ul class="column">
    //for each element in the results, execute a function
    //also, we reversed the order (e.g. start at the bottom and go up
    $($('ul.column>li').get().reverse()).each(function(outer) {

        //this is the current <li> we're running against
        var sorting = this;

        //get the same set of elements again in their current state,
        //so we can figure out where to put this one
        $($('ul.column>li').get().reverse()).each(function(inner) {

            //get the inner text of the <td class="name">
            //for the item we're trying to replace,
            //and for the current item in the inner loop
            //use localeCompare to compare the two strings alphabetically
            if($('td.name', this).text().localeCompare($('td.name', sorting).text()) > 0) {

                //if the one we're trying to sort goes after the current one
                //alphabetically, remove it from its current position
                //and insert it after the current one
                this.parentNode.insertBefore(sorting.parentNode.removeChild(sorting), this);
            }
        });
    });
}

We can make it a little more reusable by passing in the selector for the list and the key:

sort('ul.column>li', 'td.name');

function sort(list, key) {
    $($(list).get().reverse()).each(function(outer) {
        var sorting = this;
        $($(list).get().reverse()).each(function(inner) {
            if($(key, this).text().localeCompare($(key, sorting).text()) > 0) {
                this.parentNode.insertBefore(sorting.parentNode.removeChild(sorting), this);
            }
        });
    });
}

Do keep in mind this requires jQuery, so you'll need a reference to it in your <head>:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

And this function should be called at some point in the page after the list is written in the HTML.

like image 93
Rex M Avatar answered Nov 01 '22 03:11

Rex M


Mine answer is longer :p but work.

function SortLIs() {
    var ColumnUL = $("ul.column");
    var Columns  = $(ColumnUL).children("li");
     
    var ColumnNames    = new Array();
    var Columns_byName = new Array();
    var Columns_Count  = Columns.length;
    for(var i = 0; i <  Columns_Count; i++) {
        var aColumn = Columns[i];
        var aTD     = $(aColumn).find(".name");
        var aTDName = aTD.text();
        ColumnNames.push(aTDName);
        Columns_byName[aTDName] = aColumn;

        $(aColumn).remove();
    }
     
    ColumnNames.sort(function(a, b){
        return (a >  b) - (a <  b);
    });
     
    for(var i = 0; i <  Columns_Count; i++) {
        var aName = ColumnNames[i];
        ColumnUL.append(Columns_byName[aName]);
    }
}

EDIT: I saw you said that you are not good at JS. So here is the bigger picture for you.

(1) Add The following code to the header of the HTML. This will use jQuery library.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

(2) Add the 'sortLIs' code just right after the above code

<script>
<!--
function SortILs() {
    ...
}
-->
</script>

(3.1) If you want the sorting to begin at the load time. Add this right after the above code.

<script>
<!--
$(document).ready(function(){
    SortILs();
});
-->
</script>

(3.2) Otherwise, you call the function from an event.

Hope this helps.

like image 45
NawaMan Avatar answered Nov 01 '22 02:11

NawaMan