1

I have many lists with different items:

<div id="listsContainer">
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
</div>

There are lists with 2 elements and others lists with 3 elements etc.
I would like to add empty elements to the lists that contains fewer elements than that which contains many elements to have lists with the same number of elements.

enter image description here

I tried so and it works:

$("ul").each(function() {
    $( this ).find("li").addClass("total-elements"+ $(this).children().length );
    if($(this).children().length == 3) {
        $(this).append( "<li></li>" );
    }
    if($(this).children().length == 2) {
        $(this).append( "<li></li><li></li>" );
    }
});

jsFiddle

The problem is that I don't know how many items have the list with many items (is not always 4).

Is there a way to check which list contains many elements than the others dynamically and add elements to the other lists to achieve lists with equal number of elements?

Mustapha Aoussar
  • 5,833
  • 15
  • 62
  • 107

3 Answers3

1

You have to check for max length first Please check this

var max = 0;
$("ul").each(function() {
    if($(this).children('li').length > max)
        max = $(this).children('li').length;
});
$("ul").each(function() {

    if($(this).children('li').length < max ) {
        for(var i = $(this).children('li').length ; i < max;i++)
     $(this).append( "<li></li>" );
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="listsContainer">
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
</div>
Ammar
  • 719
  • 6
  • 21
1

I'd suggest creating a simple plug-in, like the following:

// creating a simple plug-in:
(function($) {
  $.fn.listEqualize = function(opts) {
    // in the plug-in, in this scope, 'this' is the jQuery collection.
    // we're getting an array of the number of children in each
    // element returned by the selector:
    var childCount = this.map(function() {
        // 'this' is a DOM node, over which map is iterating,
        // returning the number of element-children:
        return this.children.length;
      // converting to an array of values:
      }).get(),
      // finding the largest value in the array, using Array.prototype.reduce:
      largestCount = childCount.reduce(function(a, b) {
        // whichever of the two numbers (the previous or current),
        // we keep it:
        return a > b ? a : b;
      }),
      // initialising a variable for later use:
      delta,
      // creating an <li> element:
      li = document.createElement('li');

    return this.each(function() {
      // finding the difference between the number of children
      // of this element, and the largest number of children:
      delta = largestCount - this.children.length;

      for (var i = 0; i < delta; i++) {
        // appending a as many cloned <li> elements as needed
        // to equalize the <ul> elements:
        this.appendChild(li.cloneNode());
      }
    });
  };
})(jQuery);


$('ul').listEqualize();

(function($) {
  $.fn.listEqualize = function(opts) {
    var childCount = this.map(function() {
        return this.children.length;
      }).get(),
      largestCount = childCount.reduce(function(a, b) {
        return a > b ? a : b;
      }),
      delta,
      li = document.createElement('li');
    return this.each(function() {
      delta = largestCount - this.children.length;
      
      for (var i = 0; i < delta; i++) {
        this.appendChild(li.cloneNode());
      }
    });
  };
})(jQuery);


$('ul').listEqualize();
ul {
  list-style-type: none;
  float: left;
}

li {
  margin: 0 0 0.2em 0;
  padding: 0.2em 0.4em;
  box-sizing: border-box;
  border: 2px solid #000;
  border-radius: 0.5em;
  height: 1.5em;
}

li:first-child {
  border-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="listsContainer">
  <ul>
    <li>lorem lipsum</li>
    <li>lorem lipsum</li>
  </ul>
  <ul>
    <li>lorem lipsum</li>
    <li>lorem lipsum</li>
    <li>lorem lipsum</li>
  </ul>
  <ul>
    <li>lorem lipsum</li>
    <li>lorem lipsum</li>
    <li>lorem lipsum</li>
    <li>lorem lipsum</li>
  </ul>
</div>

References:

Bibliography:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
1

Try

var elem = $("#listsContainer ul");
elem.each(function (i, el) {
    var j = Math.max.apply($,
      $.map(elem, function (v, k) {
        return $("> li", v).length
      }));
    while ($("> li", el).length < j) {
        $("<li>").appendTo(el)
    }
})

See JavaScript: min & max Array values?

var elem = $("#listsContainer ul");
elem.each(function (i, el) {
    var j = Math.max.apply($,
      $.map(elem, function (v, k) {
        return $("> li", v).length
      }));
    while ($("> li", el).length < j) {
        $("<li>").appendTo(el)
    }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="listsContainer">
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
    <ul>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
        <li>lorem lipsum</li>
    </ul>
</div>
Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177