Jquery - sort DIV's by innerHTML of children
Asked Answered
T

5

40

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.

Truditrudie answered 20/10, 2011 at 5:57 Comment(3)
you cant assign same ids in html. id's should be differentOzenfant
that's a little embarrassing - the DIV's now have unique id'sTruditrudie
Never too late too clarify: Tinysort can sort by child innerHTML: tinysort.sjeiti.com/#subselectionAccentuate
S
78

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.

Schoolroom answered 20/10, 2011 at 9:43 Comment(6)
Excellent - this works nicely and I'm going to implement a version of this with the plugin. Much appreciated!Truditrudie
this code block $("#sortThis>div").tsort({attr:"data-price"}); = AwesomeChannelize
I was looking for jquery sorting, and you gave me the whole solution. Thx for saving time. :)Unfortunate
@ShawnChin tinysort.sjeiti.com/scripts/jquery.tinysort.js is no more exists and throwing 404 Error, and hence, the jsfiddle jsfiddle.net/6guj9 is no longer working. Please update your answer.Rhonda
Thank you very much! #yearslostFenny
If anyone else can't figure out why the results may be screwy. It could be because of upper/lower. Change these two lines: var vA = $(keySelector, a).text().toLowerCase(); var vB = $(keySelector, b).text().toLowerCase();Herder
C
10

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);

}
Comma answered 20/10, 2011 at 8:55 Comment(2)
Nice work! I made a small change and it works nicely: changed '=' to '==' in the IF statements.Truditrudie
Nice! I'm using it with JQM ListView. Works like a charm.Inequality
D
1

Use my jquery plugin SortContent :

$('#sortThis').sortContent({asc:true});

You can use helper to sort according to the suitable conten that you want.

$('#sortThis').sortContent({asc:true,helper:function(e){return $(e).find('.price').html()}})

if you want to reverse order ,set false to asc option

Another note, you can select directly children of div instead of parent: It is the same :

$('#sortThis>div').sortContent({asc:true,helper:function(e){return $(e).find('.price').html()}})

DEMO :

http://jsfiddle.net/abdennour/ytmry/

Danyel answered 13/9, 2013 at 16:30 Comment(0)
S
1

The first part of the marked answer does not sort correctly, I tested it using numbers from 1 - 100 and it misinterpreted anything under 10. The reason being it works on a text value and the ASCII code instead of the actual numeric value.

Here I have converted the text values to Integers using parseInt() before sorting.

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

Then we call it the same

sortUsingNestedText($('#sortThis'), "div", "span.price");
Sikko answered 9/2, 2016 at 9:36 Comment(0)
C
0

this was work for me. This bellow code short the div in low to high base on the price text.

        var gridItems = $("#sortThis").children("div");

        gridItems.sort(function(a, b) {
            return $('.price',a).text() - $('.price',b).text();
        });

        $("#sortThis").append(gridItems);
Confidant answered 20/4, 2021 at 10:16 Comment(1)
Please add some explanation to your answer such that others can learn from itLangur

© 2022 - 2024 — McMap. All rights reserved.