Reputation: 9123
I have a sorting method that I want to sort my divs based on their data-position
attribute. At the moment, for some reason the function sorts the divs based only on the first digit, and not the whole number. Here is an example in my html
which shows that:
html
<div class="parent" data-position="1">
...
</div>
<div class="parent" data-position="27">
...
</div>
<div class="parent" data-position="3">
...
</div>
Here's the js
$('body').on('click', '.new_comments', function(e) {
var divArr = $(".parent");
divArr.sort(function(a, b) {
return $(a).attr('data-position') > $(b).attr('data-position') ? 1: -1;
});
$(".comments_container").append(divArr);
});
Any idea why it does this and how to fix it?
Upvotes: 2
Views: 712
Reputation:
Convert the string data to numbers.
$('body').on('click', 'button', function(e) {
var divArr = $(".parent");
divArr.sort(function(a, b) {
return +$(a).attr('data-position') > +$(b).attr('data-position') ? 1 : -1;
});
$(".comments_container").append(divArr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<button>CLICK ME</button>
<div class="comments_container">
<div class="parent" data-position="1">
1 </div>
<div class="parent" data-position="27"> 27 </div>
<div class="parent" data-position="3"> 3 </div>
</div>
And I would first gather the attributes instead of doing it repeatedly in the callback.
$('body').on('click', 'button', function(e) {
$(".parent")
.map((i, el) => ({el: el, pos: +el.dataset.position}))
.sort((a, b) => a.pos > b.pos ? 1 : -1)
.map((i, {el}) => el)
.appendTo(".comments_container");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<button>CLICK ME</button>
<div class="comments_container">
<div class="parent" data-position="1"> 1 </div>
<div class="parent" data-position="27"> 27 </div>
<div class="parent" data-position="3"> 3 </div>
</div>
I also included some modern syntax in this solution
Upvotes: 3
Reputation: 24965
$(a).attr('data-position')
Attr returns the attribute value as a string, so you're comparison is comparing strings, not numbers, which is what you are expecting I assume. Instead of using attr() use data().
$(a).data('position')
The difference between the two is that jQuery will try to auto convert the value in the attribute to a number if it can when you use data()
. So with the values converted to numbers, you should see the sorting you expect.
Upvotes: 5