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:
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);
};
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With