9

My question is very similar to a number of others I've found on Stack Overflow, but not quite the same.

I'd like to sort list items based on the content of a span contained within each item -- but using a sort order that I can define. Here's the HTML for a sample list item:

<li>
    <span class="fname">John</span>
    <span class="lname">Doe</span>
    <span class="year">Sophomore</span>
</li>

I want to sort based on the content of the "year" span, but chronologically rather than alphabetically. The order, obviously, needs to be:

  • Freshman
  • Sophomore
  • Junior
  • Senior

How can I do this?

Just for reference, I'm using the following jQuery code (which works perfectly) to sort alphabetically by last name:

function sortByLastName(){
    var myList = $('#foo ul');
    var listItems = myList.children('li').get();
    listItems.sort(function(a,b){
        var compA = $(a).find('.lname').text().toUpperCase();
        var compB = $(b).find('.lname').text().toUpperCase();
        return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
    });
    $(myList).append(listItems);
};
1
  • provide your code please Commented Jul 6, 2011 at 4:46

3 Answers 3

11

To match your sortByLastName() function, this would work:

function sortByYear(){
  var myYears = ['Freshman', 'Sophomore', 'Junior', 'Senior'];
  var myList = $('#foo ul');
  var listItems = myList.children('li').get();
  listItems.sort(function(a,b){
    var compA = $.inArray($(a).find('.year').text(), myYears);
    var compB = $.inArray($(b).find('.year').text(), myYears);
    return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
  });
  $(myList).append(listItems);
}

Just use $.inArray() to find the indices of each school year within the array. Note that this will return -1 for values not found in the array, which will put those elements at the top of your list.

Sign up to request clarification or add additional context in comments.

Comments

6

One simple way would be to create an array with your expected values.

var years=['Freshman', 'Sophomore', 'Junior', 'Senior' ];

Then when you sort your elements, compare indexes.

listItems.sort(function(a,b){
    var indexA = $.inArray(  $(a).find('.year').text(), years );
    var indexB = $.inArray( $(b).find('.year').text(), years );
    return ( indexA < indexB) ? -1 : ( indexA > indexB) ? 1 : 0;
});

Comments

1

You have to change your sorting criterion callback. Like this:

function sortByLastName(){
    var myList = $('#foo ul');
    var listItems = myList.children('li').get();
    var scores = {
       "FRESHMAN": 0, "SOPHOMORE": 1, "JUNIOR": 2, "SENIOR": 3
    };
    listItems.sort(function(a,b){
        var compA = $(a).find('.lname').text().toUpperCase();
        var compB = $(b).find('.lname').text().toUpperCase();
        compA = scores[compA]; compB = scores[compB]; //Sort by scores instead of values
        return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
    });
    $(myList).append(listItems);
};

Hope this helps

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.