Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery - sort DIV's by innerHTML of children

I've got html that looks something like this:

<div id="sortThis"> <div id="1">Price:<span class="price">20</span><span class="style">blue</span></div> <div id="2">Price:<span class="price">23</span><span class="style">red</span></div> <div id="3">Price:<span class="price">10</span><span class="style">red</span></div> <div id="4">Price:<span class="price">29</span><span class="style">green</span></div> <div id="5">Price:<span class="price">35</span><span class="style">blue</span></div> </div> 

And I want to be able to sort by .price or by .style

I suspect that this post partially answers my question: Sort Divs in Jquery Based on Attribute 'data-sort'?

And this plugin comes close to doing what I need (since it can handle child attributes) but it does not seem to go as far as children's innerHTML: http://tinysort.sjeiti.com/

Any help will be appreciated by this noob.

like image 919
iammatthew2 Avatar asked Oct 20 '11 05:10

iammatthew2


2 Answers

To do this sort directly using the child values and without a plugin, you could use something like:

function sortUsingNestedText(parent, childSelector, keySelector) {     var items = parent.children(childSelector).sort(function(a, b) {         var vA = $(keySelector, a).text();         var vB = $(keySelector, b).text();         return (vA < vB) ? -1 : (vA > vB) ? 1 : 0;     });     parent.append(items); } 

Sorting by price can then be done as such:

sortUsingNestedText($('#sortThis'), "div", "span.price"); 

The function is parametrised so that it can be easily reused with other divs and different sort keys.

Here's a demo: http://jsfiddle.net/tc5dc/


Using the tinysort plugin

Alternatively, if you can benefit from the features provided by the tinysort plugin (mentioned in question), you could dynamically augment your divs to suit the plugin.

Check out this demo: http://jsfiddle.net/6guj9/

In the example, we first add the price and style values as data attributes of the holding div:

var sortThis = $('#sortThis').children("div"); sortThis.each(function() {     var p = $(this);     p.attr("data-price", p.find("span.price").text());     p.attr("data-style", p.find("span.style").text()); }); 

We're then free to use tinysort to sort on the relevant attributes. Sorting by price would be simply:

$("#sortThis>div").tsort({attr:"data-price"}); 

Changing the sort order and keys can be done by simply passing in different config objects. The linked demo shows one way to do this, but you can probably come up with a better scheme to suit your needs.

like image 178
Shawn Chin Avatar answered Sep 28 '22 06:09

Shawn Chin


You can sort with jquery by doing

var mylist = $('ul'); var listitems = mylist.children("li"); listitems.sort(function(a, b) {    var compA = $(a).text().toUpperCase();    var compB = $(b).text().toUpperCase();    return (compA < compB) ? -1 : (compA > compB) ? 1 : 0; }) $(mylist).append(listitems); 

It automaticly sort by price if you do

var mylist = $('#sortThis'); var listitems = mylist.children("div"); listitems.sort(function(a, b) {    var compA = $(a).text().toUpperCase();    var compB = $(b).text().toUpperCase();     console.log((compA < compB) ? -1 : (compA > compB) ? 1 : 0);    return (compA < compB) ? -1 : (compA > compB) ? 1 : 0; }) $(mylist).append(listitems); 

Ill see if i cant scratch something out with an if :)


Got something like:

if(sortorder === 'price') {      var mylist = $('#sortThis');     var listitems = mylist.children("div");     listitems.sort(function(a, b) {        var compA = $(a).children('.price').text().toUpperCase();        var compB = $(b).children('.price').text().toUpperCase();        return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;     })     $(mylist).append(listitems);  } else if (sortorder === 'style') {      var mylist = $('#sortThis');     var listitems = mylist.children("div");     listitems.sort(function(a, b) {        var compA = $(a).children('.style').text().toUpperCase();        var compB = $(b).children('.style').text().toUpperCase();        return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;     })     $(mylist).append(listitems);  } 
like image 37
Marco Johannesen Avatar answered Sep 28 '22 06:09

Marco Johannesen