18

Possible Duplicate:
Sort element by numerical value of data attribute

I want to reorganize divs according to a data attribute set on them, ranging from highest integer to lowest. Right now, I push all the data into an array and sort that but I'm not sure how to proceed. How can I use this to reorganize divs inside their parent div?

var prices = new Array();
$(this).children('.listing-item').each(function() {
    var price = parseInt($(this).attr('data-listing-price'));
    prices.push(price)
});
prices.sort(function(a,b){return b-a});

This gets me an array like 139,129,129,109,109,84 for example. Now my idea was to loop through the divs another time with a selector like this:

$('.listing-item[data-listing-price="' + prices[0] + '"]')

but I'm not sure how to move the divs (the div with the highest data-attribute integer should move to the top and so on. Any idea?

Community
  • 1
  • 1
Galadre
  • 619
  • 3
  • 6
  • 15

3 Answers3

41

Here is the solution

HTML:

<div id="list">
  <div class="listing-item" data-listing-price="2">2</div>
  <div class="listing-item" data-listing-price="3">3</div>
  <div class="listing-item" data-listing-price="1">1</div>
  <div class="listing-item" data-listing-price="4">4</div>
</div>

JS:

var divList = $(".listing-item");
divList.sort(function(a, b){
    return $(a).data("listing-price")-$(b).data("listing-price")
});
$("#list").html(divList);

JSFiddle:

http://jsfiddle.net/bittu4u4ever/ezYJh/1/

Prisoner
  • 27,391
  • 11
  • 73
  • 102
Sandeep
  • 2,041
  • 21
  • 34
  • The callback should return a negative number, positive number or `0`, not a boolean. – Felix Kling Jan 21 '13 at 12:34
  • Updated. But both ways work... ;) – Sandeep Jan 21 '13 at 12:35
  • Returning a boolean only *seems* to work, depending on the data (and algorithm) you can get unexpected results (because you make `a` to be always equal or larger than `b`, but never smaller). Read more about [`Array.sort`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort). – Felix Kling Jan 21 '13 at 12:37
  • Thanks, this works fine! As Felix said this question is a bit of a duplicate but this answer still helps more than using the answer from the other question. – Galadre Jan 21 '13 at 12:49
  • 'highest integer to lowest', it is not the good order – JohnJohnGa Jan 21 '13 at 12:50
  • 1
    Oh btw, you should not use `.html`. I hope jQuery detects this, but in the worst case it serializes all DOM element to HTML and converts them back to DOM elements. You will loose all data and event handlers bound to the elements. Just use `.append` instead. – Felix Kling Jan 21 '13 at 12:58
  • if the events are bound by `.on` then no problem at all. – Sandeep Jan 22 '13 at 04:50
  • How to sort by 2 data attributes please? ```
    2
    3
    1
    4
    ``` I would like to sort by data-group then data-listing-price
    – happysailingdude May 25 '20 at 21:12
  • I have posted my above question (about sorting by 2 data attributes) as a separate question here https://stackoverflow.com/questions/62017909/how-to-sort-divs-by-2-data-attributes I hope this may help anyone who ends up here – happysailingdude May 26 '20 at 08:42
  • to sort it by Alphabetically Try: `return String.prototype.localeCompare.call($(a).data('alpha').toLowerCase(), $(b).data('alpha').toLowerCase());` – Najam Us Saqib Jul 02 '21 at 07:39
0
var s = new Array;
var i = 0;
var x = $(".ch").length;
$(".ch").each( function() {
    s[i] = $(this).data("id");
    i++;
});
var g = s.sort(function(a,b){return a-b});
for(var c = 0; c < x; c++) {
    var div = g[c];
    var d = $(".ch[data-id="+div+"]").clone();
    var s = $(".ch[data-id="+div+"]").remove();
    $(".pa").append(d);
}

Working Fiddle

Heart
  • 508
  • 1
  • 3
  • 14
-1

You can adapt the function described here: How may I sort a list alphabetically using jQuery? and just change the sort function ('<')

<div id="foo">
    <div class="test" data-listing-price="30">30</div>
    <div class="test" data-listing-price="62">62</div>
    <div class="test" data-listing-price="11">11</div>
    <div class="test" data-listing-price="43">43</div>
</div>

In your js (highest integer to lowest):

var div = $('#foo');
var listitems = div.children('div.test').get();
listitems.sort(function (a, b) {
 return (+$(a).attr('data-listing-price') > +$(b).attr('data-listing-price')) ?
  -1 : (+$(a).attr('data-listing-price') < +$(b).attr('data-listing-price')) ? 
   1 : 0;
})
$.each(listitems, function (idx, itm) { div.append(itm); });

http://jsfiddle.net/NfVxk/

Community
  • 1
  • 1
JohnJohnGa
  • 15,446
  • 19
  • 62
  • 87
  • The callback should return a negative number, positive number or `0`, not a boolean. And neither `a` nor `b` have a `data-listing-price` property. That's not how data attributes work. You have to access them via the `.dataset` property or use `getAttribute` (or jQuery of course). – Felix Kling Jan 21 '13 at 12:34
  • Using `<` is still wrong, read more about [`Array.sort`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort). – Felix Kling Jan 21 '13 at 12:41
  • a nor b yes but $(a) and $(b) have a data-listing-price attribute – JohnJohnGa Jan 21 '13 at 12:42
  • `>` is wrong too... you have to return a positive or negative number or `0`, not a boolean. That's why Joseph is using `-` in the original answer. And honestly I don't see a point in duplicate his answer. I hope you voted to close this question as duplicate at least. – Felix Kling Jan 21 '13 at 12:47