jQuery - Sorting Parent Div with children div values not working

Viewed 82

I have an array with 2 values, 'Rank' and 'Parameter', which I'm looping to create multiple Divs within a parent Div.

jQuery(document).ready(function ($) {
var BrandArray = {
    "Brand1" : [{"Parameter":"XXX", "Rank":"#3"}],
    "Brand2" : [{"Parameter":"AAA", "Rank":"#2"}],
    "Brand3" : [{"Parameter":"MMM", "Rank":"#1"}],
}

var markup = '';
BrandArrayKeys = Object.keys(BrandArray)
jQuery.each(BrandArrayKeys, function(index, value){
    markup +=  '<div id="BrandBlock">'
    markup +=  '<div>' + BrandArray[value][0].Rank + '</div>'
    markup +=  '<div>' + BrandArray[value][0].Parameter + '</div>'
    markup +=  '</div>'    
});
$("#list").html(markup);
});

I'm then using a sort function after this to ensure that it appears sorted on Rank

jQuery(document).ready(function ($) {
    var sortedList = $('#BrandBlock').toArray().sort(function(lhs, rhs){ 
      return $(lhs).find("#Rank").text().replace( /^\D+/g, '') - $(rhs).find("#Rank").text().replace( /^\D+/g, ''); 
   });
   console.log(sortedList)
    $("#list").empty().html(sortedList);
});

This isnt working and only one 'Div' appears in the page. This formula however works when the DIV Table already resides in the HTML itself instead of being built by jQuery.

Where am I going wrong?

Find below the entire working code:

jQuery(document).ready(function($) {
  var BrandArray = {
    "Brand1": [{
      "Parameter": "XXX",
      "Rank": "#3"
    }],
    "Brand2": [{
      "Parameter": "AAA",
      "Rank": "#2"
    }],
    "Brand3": [{
      "Parameter": "MMM",
      "Rank": "#1"
    }],
  }

  var markup = '';
  BrandArrayKeys = Object.keys(BrandArray)
  jQuery.each(BrandArrayKeys, function(index, value) {
    markup += '<div id="BrandBlock">'
    markup += '<div>' + BrandArray[value][0].Rank + '</div>'
    markup += '<div>' + BrandArray[value][0].Parameter + '</div>'
    markup += '</div>'
  });
  $("#list").html(markup);
});

jQuery(document).ready(function($) {
  var sortedList = $('#BrandBlock').toArray().sort(function(lhs, rhs) {
    return $(lhs).find("#Rank").text().replace(/^\D+/g, '') - $(rhs).find("#Rank").text().replace(/^\D+/g, '');
  });
  $("#list").empty().html(sortedList);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>

<div id="list"></div>

1 Answers

There's a couple of issues here. Firstly because you're appending an element with the same id multiple times. id attributes have to be unique within the DOM. This needs to be changed to a class.

Secondly, your sort logic expects there to be an element within each #BrandBlock with an id of Rank, however this does not exist and if it did you would again be repeating identifiers and causing the same issue. Change the logic to sort by the class, and add the class in to the HTML.

With those fixes in place, the code works. Note that I also made it more succinct by using map(), Object.entries() and some arrow functions.

jQuery($ => {
  let brandArray = {Brand1:[{Parameter:"XXX",Rank:"#3"}],Brand2:[{Parameter:"AAA",Rank:"#2"}],Brand3:[{Parameter:"MMM",Rank:"#1"}]};
  
  let markup = Object.entries(brandArray).map(([key, obj]) => `<div class="brandblock"><div class="rank">${obj[0].Rank}</div><div>${obj[0].Parameter}</div></div>`);
  $("#list").html(markup);

  var sortedList = $('.brandblock').sort((lhs, rhs) => $(lhs).find(".rank").text().replace(/^\D+/g, '') - $(rhs).find(".rank").text().replace(/^\D+/g, ''));
  $("#list").html(sortedList);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>

<div id="list"></div>

Related