1

I'm trying to iterate through all the elements with a specific class to sort their children based on their value attributes. I need to sort the children separately for each parent elements.

Html structure :

<ul class="parentClass">
   <li value="1">...</li>
   <li value="10">...</li> 
   <li value="8">...</li> 
</ul>
<ul class="parentClass">
   <li value="8">...</li>
   <li value="29">...</li> 
   <li value="5">...</li> 
</ul>

JS code :

function sortAll() {
    $(".parentClass").each(function() {
        var items = $(this).children("li").sort(function(a, b) {
        var vA = $("li", a).attr("value");
        var vB = $("li", b).attr("value");
        return (vA > vB) ? -1 : (vA > vB) ? 0 : 1;
        });
        $(this).append(items);
    });
}

What I'm trying to get :

<ul class="parentClass">
   <li value="10">...</li>
   <li value="8">...</li> 
   <li value="1">...</li> 
</ul>
<ul class="parentClass">
   <li value="29">...</li>
   <li value="8">...</li> 
   <li value="5">...</li> 
</ul>

I think I misunderstood something with iteration. Could you help me to figure out my mistake?

I would also let you know that some <li> elements could have the same value.

Solution :

function sortAll() {
        $(".parentClass").each(function() {
            var items = $(this).children("li").sort(function(a, b) {
            var vA = $(a).attr("value");
            var vB = $(b).attr("value");
            return (vA > vB) ? -1 : (vA > vB) ? 0 : 1;
            });
            $(this).append(items);
        });
    }
rushelmet
  • 305
  • 2
  • 15
  • possible duplicate of [jquery sort list based on data attribute value](http://stackoverflow.com/questions/21600802/jquery-sort-list-based-on-data-attribute-value) – FuzzyTree Jul 19 '15 at 21:13

2 Answers2

1

You should use $(a) and $(b) instead of the $("li", a) and $("li", b). a and b refer to the li elements. You are trying to find the descendant lis of the li elements ($(selector, context) is the same as $(context).find(selector)). The queries return empty collections and subsequently attr returns an undefined value. Both undefined > undefined and undefined < undefined return false. The sort callback always returns 0 which leaves the order unchanged.

Ram
  • 143,282
  • 16
  • 168
  • 197
0

Please have a look at example of descending sorting with your data. There are a good answer about array sorting with a description for algorithm.

The ternary operator (vA > vB) ? -1 : (vA > vB) ? 0 : 1 that you have used is behaving weird, resulting in wrong order.

  • If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a. compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments.
  • If inconsistent results are returned then the sort order is undefined

If vA > vB // true sort a to a lower index than b

Therefore if vA < vB // true leave a and b unchanged. This is a logical error.

function sortAll() {
  
  // Define variables before loops.
  var $container, $itemsColl;
  
  $(".parentClass").each(function(key, value) {
    
    // <ul> tag
    $container = $(value);
    $itemsColl = $container.children("li");
    
    // Sort and appendTo() <ul>.
    $itemsColl.sort(function(a, b) {

        // Inverted for descendant sorting.
        return $(b).attr('value') - $(a).attr('value');
      })
      .appendTo($container);
  });
}

sortAll();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="parentClass">
  <li value="1">1</li>
  <li value="10">10</li>
  <li value="8">8</li>
</ul>
<ul class="parentClass">
  <li value="8">8</li>
  <li value="29">29</li>
  <li value="5">5</li>
</ul>
Community
  • 1
  • 1
halfzebra
  • 6,771
  • 4
  • 32
  • 47