ashes999
ashes999

Reputation: 1324

How to sort child divs in parents div based on data attribute?

I am trying to sort child divs inside a parent div using jQuery however my code is not working at all. My intention is to sort the child div elements in ascending order. Currently, my template structure is:

I am using this function to sort the child divs based on data-year attribute:

$(function() {

  $('.year').on('click', function(e) {
    e.preventDefault();
    $('#parent').find('.child').sort(function(a, b) {
      var contentA = parseInt($(a).attr('data-year'));
      var contentB = parseInt($(b).attr('data-year'));
      return (contentA > contentB) ? -1 : (contentA < contentB) ? 1 : 0;
    }).appendTo('#parent');
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown">
  <button class="btn btn-sm dropdown-toggle" type="button" id="d_li" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Sort By
          </button>
  <div class="dropdown-menu mt-1" aria-labelledby="d_li">
    <button class="small dropdown-item newest" type="button">Newest</button>
    <button class="small dropdown-item name">Name</button>
    <button class="small dropdown-item year" type="button">Year</button>
  </div>
</div>

<div id="parent">
  <div class="child" data-year="2010" data-ins="2">year 2010, ins 2</div>
  <div class="child" data-year="2000" data-ins="3">year 2000, ins 3</div>
  <div class="child" data-year="2020" data-ins="1">year 2020, ins 1</div>
</div>

After clicking on year button nothing changes, what am I doing wrong?

Upvotes: 2

Views: 884

Answers (2)

SMAKSS
SMAKSS

Reputation: 10520

Actually, if you look at sort() documentation. You can find out there is no need for ternary, less or greater than operation or whatever. If you looking for sorting an array (or in your particular case array-like element like HTML collection) you should always consider these two statements:

If compareFunction(a, b) returns less than 0, sort a to an index lower than b (i.e. a comes first).

If compareFunction(a, b) returns greater than 0, sort b to an index lower than a (i.e. b comes first).

NOTE: The compareFunction in your case is function(a, b){...}.

So you just need to stick with the first statement and subtract b from a that's all.

Then your final code should be something like this:

$(function() {

  $('.year').on('click', function(e) {
    e.preventDefault();
    $('#parent').find('.child').sort(function(a, b) {
      var contentA = parseInt($(a).attr('data-year'));
      var contentB = parseInt($(b).attr('data-year'));
      return contentA - contentB
    }).appendTo('#parent');
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown">
  <button class="btn btn-sm dropdown-toggle" type="button" id="d_li" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Sort By
          </button>
  <div class="dropdown-menu mt-1" aria-labelledby="d_li">
    <button class="small dropdown-item newest" type="button">Newest</button>
    <button class="small dropdown-item name">Name</button>
    <button class="small dropdown-item year" type="button">Year</button>
  </div>
</div>

<div id="parent">
  <div class="child" data-year="2010" data-ins="2">year 2010, ins 2</div>
  <div class="child" data-year="2000" data-ins="3">year 2000, ins 3</div>
  <div class="child" data-year="2020" data-ins="1">year 2020, ins 1</div>
</div>

Upvotes: 1

Kalimah
Kalimah

Reputation: 11437

You need to swap the operators > and < in sort function.

$(function() {

  $('.year').on('click', function(e) {
    e.preventDefault();
    $('#parent').find('.child').sort(function(a, b) {
      var contentA = parseInt($(a).attr('data-year'));
      var contentB = parseInt($(b).attr('data-year'));
      return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
    }).appendTo('#parent');
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown">
  <button class="btn btn-sm dropdown-toggle" type="button" id="d_li" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Sort By
          </button>
  <div class="dropdown-menu mt-1" aria-labelledby="d_li">
    <button class="small dropdown-item newest" type="button">Newest</button>
    <button class="small dropdown-item name">Name</button>
    <button class="small dropdown-item year" type="button">Year</button>
  </div>
</div>

<div id="parent">
  <div class="child" data-year="2010" data-ins="2">year 2010, ins 2</div>
  <div class="child" data-year="2000" data-ins="3">year 2000, ins 3</div>
  <div class="child" data-year="2020" data-ins="1">year 2020, ins 1</div>
</div>

Upvotes: 1

Related Questions