executable
executable

Reputation: 3600

Generate html in for each with closing tag every 4 loop

I'm trying to generate the following html :

<div class="row">
    <div class="col-md-3"></div>
    <div class="col-md-3"></div>
    <div class="col-md-3"></div>
    <div class="col-md-3"></div>
</div>
<div class="row">
    <div class="col-md-3"></div>
    <div class="col-md-3"></div>
    <div class="col-md-3"></div>
    <div class="col-md-3"></div>
</div>
<div class="row">
    <div class="col-md-3"></div>
</div>

So I tried the following :

var response = '[{"id":7},{"id":10},{"id":15},{"id":11},{"id":14},{"id":9},{"id":8},{"id":12},{"id":1}]'
var json = $.parseJSON(response);
var add_html = "";
$(json).each(function (i, val) {
    if (i % 4 == 0){
        add_html += "<div class='row'>";
    }
    add_html = add_html + "<div class='col-md-3'></div>";
    if (i % 4 == 0){
        add_html = add_html + "</div>";
    }
});
/*
if (i % 4 != 1){
    add_html = add_html + "</div>";
}
*/
console.log(add_html)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

But doesn't output the desired result

Upvotes: 0

Views: 72

Answers (3)

Karan
Karan

Reputation: 12629

Try like below. And check changes with comment.

There are two changes in your code.

  1. You need to open your row div with i%4 == 0 and close it with i%4 == 3.
  2. Once each loop complete you should check if (json.length - 1) % 4 != 3 then need to add </div>

var response = '[{"id":7},{"id":10},{"id":15},{"id":11},{"id":14},{"id":9},{"id":8},{"id":12},{"id":1}]'
var json = $.parseJSON(response);

var add_html = "";
$(json).each(function(i, val) {
  if (i % 4 == 0) {
    add_html += "<div class='row'>";
  }
  add_html = add_html + "<div class='col-md-3'></div>";
  // Change 1 - Update condition here to compare with 3
  if (i % 4 == 3) {
    add_html += "</div>";    
  }
});

// Change 2 - Add additional condition
if ((json.length - 1) % 4 != 3) {
  add_html += "</div>";
}

console.log(add_html)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


Old version

  1. Initialize add_html with opening row div.
  2. When i % 4 == 3 which means it is forth index add closing div and open a new one.
  3. Once each loop completes then add closing div.

Note - This has one bug. It will add extra <div class='row'></div> when json array is of json.length % 4 == 0 .

var response = '[{"id":7},{"id":10},{"id":15},{"id":11},{"id":14},{"id":9},{"id":8},{"id":12},{"id":1}]'
var json = $.parseJSON(response);

// Initialize your html with opening row div
var add_html = "<div class='row'>";
$(json).each(function(i, val) {
  add_html = add_html + "<div class='col-md-3'></div>";
  if (i % 4 == 3) { // <- Update condition here to compare with 3
    // Close current row div and open new one
    add_html += "</div>";
    add_html += "<div class='row'>";
  }
});

// End your html with closing row div
add_html = add_html + "</div>";

console.log(add_html)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Upvotes: 1

Rory McCrossan
Rory McCrossan

Reputation: 337646

To achieve your goal you could batch the original array in to groups of 4 and then use map() to iterate through that and create the HTML you require:

var json = $.parseJSON('[{"id":7},{"id":10},{"id":15},{"id":11},{"id":14},{"id":9},{"id":8},{"id":12},{"id":1}]');

let perChunk = 4;
json = json.reduce((all, one, i) => {
  const ch = Math.floor(i / perChunk);
  all[ch] = [].concat((all[ch] || []), one);
  return all
}, [])

let html = json.map(chunk => `<div class="row">${chunk.map(item => `<div class="col-md-3"></div>`).join('')}</div>`).join('');
console.log(html);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Upvotes: 1

pingzhou
pingzhou

Reputation: 21

        var response = '[{"id":7},{"id":10},{"id":15},{"id":11},{"id":14},{"id":9},{"id":8},{"id":12},{"id":1}]'
        var json = JSON.parse(response);
        const add_html = json.map(() => '<div class="col-md-3"></div>').reduce((pre, cur) => {
            const arr = pre[pre.length - 1];
            if (arr.length >= 4) {
                pre.push([cur])
            } else {
                arr.push(cur);
            }
            return pre;
        }, [[]]).map(item => `<div class="row">${item.join('')}</div>`).join('')

Upvotes: 0

Related Questions