Cameron
Cameron

Reputation: 28803

Loop through array and add to string based on count

I'm trying to loop through an array of items and build up a HTML structure based on what count we are at through the array.

It should wrap every item in a cell and every 4 items in a row and every 8 items in a column div.

Here is the JavaScript:

var html = ''; // for those that were asking where html was...

for(var i=0;i<response.length;i++)
{
     // for first and every 8 items
     if(i == 0 || i % 8 === 0)
    {
        console.log('columnstart');
        html = html + '<div class="column">';
    }

    //  for first and every 4 items
    if(i == 0 || i % 5 === 0)
    {
        console.log('rowstart');
        html = html + '<div class="row">';
    }

    // after every 4 items BUT NOT the first
    if(i % 4 === 0 && i !== 0) 
    {
        console.log('rowend');
        html = html + '</div>';
    }

    // after every 8 items BUT NOT the first
    if(i == response.length && i !== 0 || i % 7 === 0 && i !== 0)
    {
        console.log('columnend');
        html = html + '</div>';
    }

    console.log('cell');
    html = html + '<div class="cell"></div>';
}

and here is an example of how the HTML should be being rendered:

<div class="column">
    <div class="row">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
    </div>
    <div class="row">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
    </div>
</div>
<div class="column">
    <div class="row">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
    </div>
    <div class="row">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
    </div>
</div>

However it seems my counts are off...

Because I get the following in the console:

columnstart
rowstart
cell
cell
cell
cell
cell
rowend
rowstart
cell
cell
cell
columnend
columnstart
cell
rowend
cell
rowstart
cell
cell

Upvotes: 2

Views: 116

Answers (5)

Uri Goren
Uri Goren

Reputation: 13690

I'm afraid you misinterpreted the modulo (%) operator

i % 7==0 means that i is divisible by 7 what you want is i % 8==7

I always find it more clear with a switch statement:

while (response.length%8!=7)
    response.push('');
var html='';
for(var i=0;i<response.length;i++)
{
    switch (i%8) {
        case 0:  html = html + '<div class="column"><div class="row">'+response[i];break;
        case 4:  html = html + '</div><div class="row">'+response[i];break;
        case 7:  html = html + response[i]+'</div></div>';break;
        default: html = html + response[i];
    }
}

Upvotes: 0

musefan
musefan

Reputation: 48415

Well, it seems there was a lot wrong with your logic, so I just rewrote the whole thing. Basically, treat the first and last element as special cases, that way the counting logic doesn't need to be as complicated.

See comments for more information:

var html = '';

for (var i = 0; i < response.length; i++) {
    // If first element, open column and row and add first cell.
    if (i == 0) {
        html = html + '<div class="column">';
        html = html + '<div class="row">';
        html = html + '<div class="cell"></div>';

        // If the first element, is also the last, then close row and column now.
        if (i == response.length - 1) {
            html = html + '</div>';
            html = html + '</div>';
        }
    }
    // If last element, add last cell and close row and column.
    else if (i == response.length - 1) {
        html = html + '<div class="cell"></div>';
        html = html + '</div>';
        html = html + '</div>';
    }
    // Otherwise, process based on count.
    else {
        // If end of row, then close row.
        if (i % 4 == 0) {
            html = html + '</div>';
        }

        // If end of column close column, open new column.
        if (i % 8 == 0) {
            html = html + '</div>';
            html = html + '<div class="column">';
        }

        // If end of row, open new row.
        if (i % 4 == 0) {
            html = html + '<div class="row">';
        }

        // Insert the cell.
        html = html + '<div class="cell"></div>';
    }
}

Here is a working example

Upvotes: 2

JSP64
JSP64

Reputation: 1462

Should be

for(var i=0;i<response.length;i++)
{
 // Before 1st and every 8 cells
 if(i % 8 == 0)
{
    console.log('columnstart');
    html = html + '<div class="column">';
}

//  Before 1st and every 4 items
if(i % 4 == 0)
{
    console.log('rowstart');
    html = html + '<div class="row">';
}

console.log('cell');
html = html + '<div class="cell"></div>';

// after every 4th cell added
if(i % 4 == 3) 
{
    console.log('rowend');
    html = html + '</div>';
}

// after every 8th cell added
if(i % 8 ==7)
{
    console.log('columnend');
    html = html + '</div>';
}


}

Upvotes: 0

putnampp
putnampp

Reputation: 341

for(var i=0;i<response.length;++i)
{
     // for first and every 8 items
     if(i % 8 == 0) {
         console.log('columnstart');
         html = html + '<div class="column">';
     }

     //  for first and every 4 items
     if(i % 4 == 0) {
         console.log('rowstart');
         html = html + '<div class="row">';
     }

     console.log('cell');
     html = html + '<div class="cell"></div>';

     // after every 4 items BUT NOT the first
     if(i % 4 == 3) {
         console.log('rowend');
         html = html + '</div>';
     }

     // after every 8 items
     if(i % 8 == 7) {
         console.log('columnend');
         html = html + '</div>';
     }
}

Upvotes: 0

Alvin Thompson
Alvin Thompson

Reputation: 5448

A couple of tyypos:

//  for first and every 4 items
if(i == 0 || i % 5 === 0)
{
    console.log('rowstart');
    html = html + '<div class="row">';
}

should be:

//  for first and every 4 items
if(i == 0 || i % 4 === 0)
{
    console.log('rowstart');
    html = html + '<div class="row">';
}

a typpo or two and an issue with logic and precedence:

// after every 8 items BUT NOT the first
if(i == response.length && i !== 0 || i % 8 === 0 && i !== 0)
{
    console.log('columnend');
    html = html + '</div>';
}

should be:

// after every 8 items BUT NOT the first
if(i === response.length - 1 || (i !== 0 && i % 8 === 0))
{
    console.log('columnend');
    html = html + '</div>';
}

Upvotes: 0

Related Questions