kawnah
kawnah

Reputation: 3404

Loop through elements and incrementally apply CSS rule for each one

I have a grid layout, with variable amounts of elements in each one. I would like to dynamically add inline grid-column CSS rules for each element that is present in a div by looping through each <ul> with a class of .list. So the output of the code in HTML needs to be:

<ul class="list" style="grid-column: 1;"></ul>
<ul class="list" style="grid-column: 2;"></ul>
<ul class="list" style="grid-column: 3;"></ul>

Below is the code sample:

// iterate through each div named "list item"
$(".list-item").each(function() {
  // get the amount of each ul within the div
  var listAmount = $(".list-item > .sub-list").size();
  // I also tried:
  // var listAmount = $(".list-item > .sub-list").length;

  // for each one that is present within the div,
  for (var i = 0; i < listAmount.length; i++) {
    // apply the CSS "grid-column" of 1, 2, 3, 4 which is defined by i
    $(".sub-list").css("grid-column", i);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="list-item">
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
</div>

<div class="list-item">
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
</div>

<div class="list-item">
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
</div>

Unfortunately the inline styles aren't applying as expected.

My JS snippet is commented with my train of thought. I don't understand why this doesn't work, what am I doing wrong?

Upvotes: 2

Views: 2125

Answers (3)

Javier Gonzalez
Javier Gonzalez

Reputation: 1015

Here is my solution:

  1. Iterate over each .list-item

  2. Search ul.list using each .list-item element as filter

  3. apply the grid-column style to each ul.list. Note how the each function arguments allows you reference the current index and object (i and obj)

// iterate through each div named "list item"
$(".list-item").each(function(a, listItem) {
  var list = $(listItem);
  var sublist = $("ul.list", list);
  sublist.each(function(i, obj){
    $(obj).css("grid-column", i+1);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="list-item">
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
</div>

<div class="list-item">
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
</div>

<div class="list-item">
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
  <ul class="list">
    <li class="list__header"><a href="#">Main Item</a></li>
  </ul>
</div>

Upvotes: 1

azs06
azs06

Reputation: 3517

The way you are looping through you are not actually going through sub lists. You have to loop though each sub-list within each list and add css to it.

Here is a working example

var listItems = jQuery('.list-item');
listItems.each(function(index, value) {
  $(value).find('.list').each(function(i, list) {
    //index will start from 0, adding 1 to make grid-column 
    // start from 1
    //adding empty string to convert it into a string
    var columnSize = i + 1 + "";
    $(list).css('grid-column', columnSize);
  });
});
.list-item {
  display: grid;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <div class="list-item">
    <ul class="list">
      <li class="list__header"><a href="#">Main Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li class="list__header"><a href="#">Main Item</a></li>
    </ul>
  </div>

  <div class="list-item">
    <ul class="list">
      <li class="list__header"><a href="#">Main Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li class="list__header"><a href="#">Main Item</a></li>
    </ul>
  </div>

  <div class="list-item">
    <ul class="list">
      <li class="list__header"><a href="#">Main Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
      <li><a href="#">Item</a></li>
    </ul>
    <ul class="list">
      <li class="list__header"><a href="#">Main Item</a></li>
    </ul>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</body>

</html>

Here is a plunker of the above snippet https://plnkr.co/edit/CVthyQ8mcYUFKpomfFar?p=preview

Upvotes: 1

sliptype
sliptype

Reputation: 2964

You are applying the style to all sub-lists every iteration. I think you need to change this:

var subLists = $(".list-item > .sub-list");

for (var i = 0; i < subLists.length; i++) {
  subLists.get(i).css("grid-column", i);
}

Upvotes: 0

Related Questions