Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery sort order by data attribute

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.

like image 514
ultraloveninja Avatar asked Aug 10 '26 15:08

ultraloveninja


1 Answers

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.

like image 103
Tyler Roper Avatar answered Aug 13 '26 05:08

Tyler Roper