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);
};
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);
};
Share
Improve this question
asked Jul 6, 2011 at 4:28
40 Degree Day40 Degree Day
2,7334 gold badges22 silver badges15 bronze badges
1
- provide your code please – Kanishka Panamaldeniya Commented Jul 6, 2011 at 4:46
3 Answers
Reset to default 11To 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.
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;
});
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