3

I have some items in a div that are have the data attribute of data-order attached to them:

<div class="list">
   <a href="#" data-order="4">Thing 4</a>
   <a href="#" data-order="3">Thing 3</a>
   <a href="#" data-order="1">Thing 1</a>
   <a href="#" data-order="2">Thing 2</a>
</div>

But I'm trying to get them so they display the numerical order (ascending - 1,2,3, etc.):

<div class="list">
   <a href="#" data-order="1">Thing 1</a>
   <a href="#" data-order="2">Thing 2</a>
   <a href="#" data-order="3">Thing 3</a>
   <a href="#" data-order="4">Thing 4</a>
</div>

I have this:

  $(".list a").sort(function(a, b) {
    return $(a).attr("data-order") > $(b).attr("data-order");
  }).each(function() {
    $(".list").prepend(this);
  });

But that seems to really mess the order up. So I'm not too sure what I'm doing incorrectly or if there might be a simpler way to go about getting them to sort correctly.

7
  • What do you expect new Date to accomplish? Commented Dec 3, 2018 at 19:16
  • Whoops! That might be a typo.... I was looking at another example that as using date to sort. Commented Dec 3, 2018 at 19:17
  • @GeorgeJempty - I updated it and removed the new Date Commented Dec 3, 2018 at 19:21
  • It's working for me now: repl.it/@dexygen/sortHrefs Commented Dec 3, 2018 at 19:24
  • 2
    @GeorgeJempty Your html is already in order. If you mix them up, it does not work. Commented Dec 3, 2018 at 19:26

2 Answers 2

15

A few things:

  1. sort should not return a boolean, but rather a negative, positive, or zero*:

    if (a  <  b) return -1; //negative
    if (a  >  b) return 1;  //positive
    if (a === b) return 0;  //0
    

    Easier expressed as:

    return a - b;
    
  2. You can use appendTo() in place of .each( .append() ), which I'd expect to perform slightly better.

  3. .attr("data-order") can be expressed as .data("order") (though this is more a matter of preference).

$(".list a")
    .sort((a,b) => $(a).data("order") - $(b).data("order"))
    .appendTo(".list");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
  <a href="#" data-order="4">Thing 4</a>
  <a href="#" data-order="3">Thing 3</a>
  <a href="#" data-order="1">Thing 1</a>
  <a href="#" data-order="2">Thing 2</a>
</div>


Taking it one step further, you could even create your own jQuery plugin/method:

$(".list").sortChildren();

$.fn.sortChildren = function() {
    this
      .children()
      .sort((a,b) => $(a).data("order") - $(b).data("order") || -1)
      .appendTo(this);

    return this;
}

$(".list").sortChildren();
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
  <a href="#" data-order="4">Thing 4</a>
  <a href="#" data-order="3">Thing 3</a>
  <a href="#" data-order="1">Thing 1</a>
  <a href="#" data-order="2">Thing 2</a>
</div>


*Thanks to charlieftl for the slight correction.

With his note that the sort() doesn't have to return -1, 0, or 1, we gain a few things:

  • We can simply do a - b to determine sort order

  • We no longer need to parse the values. The - operator can only be used with numeric values, therefore it will parse a and b on its own.

Sign up to request clarification or add additional context in comments.

2 Comments

" It should return one of three values" is not absolute. Rule is really ... positive number, negative number or zero
Cool, this makes sense of things. Thanks!
1

Change your sort comparison operator to - from > which will cast the values to numbers and the subtraction will return numeric value that is positive, negative or zero

Can also use html(function) or append(function)

$(".list").append(function() {
  return $(this).children().sort(function(a, b) {
    return $(a).attr("data-order") - $(b).attr("data-order");
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list">
  <a href="#" data-order="4">Thing 4</a>
  <a href="#" data-order="3">Thing 3</a>
  <a href="#" data-order="1">Thing 1</a>
  <a href="#" data-order="2">Thing 2</a>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.