20

I want every row in my page to display 3 thumbnails, but its stacked in one row.

How do I manage the looping? Thank you...

<?php
    foreach ($rows as $row){
?>  
        <div class="col-md-3">
            <div class="thumbnail">
                <img src="user_file/<?php echo $row->foto; ?>">
            </div>
        </div>

<?php
}
?>

This code generates stacked thumbnails in a row. How can I generate the row for every 3 columns?

This screenshot is what I got from the code:

Thisis What i got

This is what I'm looking to get:

This is what i want.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 3
    Your question makes no sense. You write, that you want to display 3 thumbnails in every row, but also that it should ever third column. Can you post a visual example, on what you want to achieve? – Peon Nov 12 '16 at 09:11
  • You want to loop to create many rows and, inside each row you want to create 3 thumbnails? Is that what you want? Are the 3 thumbnails all the same and related to the `$row` variable? In a grid system with 12 columns you would fill just 9 of them if you created 3 `
    .` Is that what you want?
    – Tom Nov 12 '16 at 10:21
  • ive been editing the question, thank you ... – Mochamad Ramdanny Lukman Nov 12 '16 at 11:20

11 Answers11

80

Edit: Originally I posted this quickly from the top of my head. Thanks, Wael Assaf for pointing out an improvement, which I have used. Also, I have added a couple of changes to the code, now it is versatile and can be used for a variable number of columns you can choose by changing the variable $numOfCols

You need to add a div for each row. Then the floating divs you have, will not just wrap around but instead will be in their own container.

The bootstrap class row is perfect for this:

Method 1 (not recommended for new versions of HTML and Browser): This method is for older version on HTML and browser because new versions of HTML and browser have inbuild functions to auto close missing tags so when you use code below it will automatically close pre-defined tag <div class="row"> rather than waiting for if condition to close that tag in result causing improper layout.

Note: you can try and observe result by inspecting elements

<?php
//Columns must be a factor of 12 (1,2,3,4,6,12)
$numOfCols = 4;
$rowCount = 0;
$bootstrapColWidth = 12 / $numOfCols;
?>
<div class="row">
<?php
foreach ($rows as $row){
?>  
        <div class="col-md-<?php echo $bootstrapColWidth; ?>">
            <div class="thumbnail">
                <img src="user_file/<?php echo $row->foto; ?>">
            </div>
        </div>
<?php
    $rowCount++;
    if($rowCount % $numOfCols == 0) echo '</div><div class="row">';
}
?>
</div>

Uses PHP modulus operator to echo the open and close of each row at the right points.

Method 2 (recommended): This method is to overcome the problem faced by method 1, as a result, causing proper layout for modern browser.

<?php
//Columns must be a factor of 12 (1,2,3,4,6,12)
$numOfCols = 4;
$rowCount = 0;
$bootstrapColWidth = 12 / $numOfCols;
foreach ($rows as $row){
  if($rowCount % $numOfCols == 0) { ?> <div class="row"> <?php } 
    $rowCount++; ?>  
        <div class="col-md-<?php echo $bootstrapColWidth; ?>">
            <div class="thumbnail">
                <img src="user_file/<?php echo $row->foto; ?>">
            </div>
        </div>
<?php
    if($rowCount % $numOfCols == 0) { ?> </div> <?php } } ?>

Note: you can try and observe result by inspecting elements

Hope this helps.

dading84
  • 1,210
  • 12
  • 18
  • +1 this is really helpful, note you can replace this part $x % 4 == 0 with the number of bootstrap columns you want to display for example for a 2 column grid you would have: $x % 2 == 0 – rhysclay Jun 29 '17 at 22:45
  • 4
    This is completely wrong. if row count is 2, then row would not be closed. – David Jul 14 '17 at 08:49
  • I voted for this answer because I had the same problem today and using google I found the solution here on stackoverflow and I found this topic that was the same problem I had today and I was able to solve it in few minutes!. thanks! – P.Davide Jul 14 '17 at 19:56
  • I had this same problem today, actually for months now, and then I tried adding the logic to this code. I thought I can never fix this because it was "html / bootstrap - related" and I'm not really good at it. But it worked! thank you so much! =) – Ken Flake Aug 31 '17 at 23:19
  • for me, when reaches 4 rows it breaks the line, creating a new set of div blocks. It's possible to adapt to work dynamically for n number of rows and 4 columns? – Igor O Mar 24 '20 at 09:35
28

You can use array_chunk(input array, size of each chunk) function to chunk your array into pieces.
php.net manual: array_chunk

Chunks an array into arrays with size elements. The last chunk may contain less than size elements.

Here is an example:

<?php

    $numberOfColumns = 3;
    $bootstrapColWidth = 12 / $numberOfColumns ;

    $arrayChunks = array_chunk($items, $numberOfColumns);
    foreach($arrayChunks as $items) {
        echo '<div class="row">';
        foreach($items as $item) {
            echo '<div class="col-md-'.$bootstrapColWidth.'">';
            // your item
            echo '</div>';
        }
        echo '</div>';
    }  
?>
Pars
  • 4,932
  • 10
  • 50
  • 88
27

No need for all this complexity. Bootstrap works within a 12 col grid system automatically. Just make sure you loop and make col size so that that evenly divides by 12 e.g. col-md-4.

This example will provide 3 per row automatically since 12 / 4 = 3.

<div class="row">
    LOOPCODE
    {
        <div class="col-md-4">
            DATA
        </div>
    }
</div>
Chris Go
  • 615
  • 7
  • 15
  • 2
    So much complexity in some of these answers, compared to something so simple. Best answer here by far! – Jordan May 17 '19 at 00:52
  • 2
    Best answer, so simple. – mimi Jul 15 '19 at 15:09
  • simple solution! – not_null May 30 '22 at 06:08
  • yeah, you can say that it can also be the correct answer as far as you are not concerned about not breaking the layout. because when you have more than 12 columns in a single row then the grid will break the layout. You have to understand the purpose of row. why it is important to have only 12 column in a single row? So others answer explaining the logic of creating 12 columns in a single row is betther than this answer. – Noman Shaikh Sep 08 '22 at 17:24
13

First You should define a variable, then right before the loop ends increment it and echo the closing row tag and open another one depending on it.

Useful steps

  • define $i = 0;
  • inside the loop make your echos.
  • right before the foreach ends increment the $i++ and make a condition : if $i % 3 == 0 then echo the closing tag of the row then generate a new row.

Code :

<div class='row'>
<?php
foreach($items as $item) {
  echo "<div class='col-lg-2'>";
      echo "<div class='item'>";
        echo 'Anythin';
      echo '</div>';
  echo '</div>';
  $i++;
  if ($i % 3 == 0) {echo '</div><div class="row">';}
}
?>
</div>

Tip : You don't really want to foreach the row, its a bad idea, make one row and foreach the items.

Wael Assaf
  • 1,233
  • 14
  • 24
4

This is a better way – to use chunk() function of Collections.

`@foreach($items->chunk(5) as $chunk)
        <ul>
            @foreach($chunk as $item)
                Item {{ $loop->iteration }}
            @endforeach 
        </ul>
 @endforeach`
Aosu Terver
  • 117
  • 2
  • 6
2

dading84's answer works fine, but i have modified it for avoid adding a last empty row. The change was simply count the number of elements in the array, then check if the last element was reached, to prevent adding new div with class row.

Code edited:

<?php
//Columns must be a factor of 12 (1,2,3,4,6,12)
$numOfCols = 4;
$rowCount = 0;
$bootstrapColWidth = 12 / $numOfCols;
$arrayCount = count($rows);
?>
<div class="row">
<?php
foreach ($rows as $row){
?>  
        <div class="col-md-<?php echo $bootstrapColWidth; ?>">
            <div class="thumbnail">
                <img src="user_file/<?php echo $row->foto; ?>">
            </div>
        </div>
<?php
    $rowCount++;
    if($rowCount % $numOfCols == 0 && $rowCount < $arrayCount) {
        echo '</div><div class="row">';
    }
}
?>
</div>

Resume:

  • Added variable $arrayCount
  • Add conditional inside the IF modulus to check if is the last row, so avoid adding new div.
  • Welcome to SO! The answer you are mentioning has been accepted. Even if it is wrong, some OP's could consider your answer as rude saying that it is wrong. Try to downvote it and you will see it. – David García Bodego Dec 28 '19 at 01:20
  • @DavidGarcíaBodego I did not realize that it could be interpreted as rude, I modified the comment to raise it from another perspective. Regards! – Ignacio Aguirre Dec 29 '19 at 01:08
0

Simple custom css solution... target rows in .listing wrapper with bottom-margin, last row has no margin-bottom.

HTML

<div class="listing">
    <div class="row">
        <div class="col-md-4">
        </div>
        <div class="col-md-4">
        </div>
        <div class="col-md-4">
        </div>
    </div>
    <div class="row">
        <div class="col-md-4">
        </div>
        <div class="col-md-4">
        </div>
        <div class="col-md-4">
        </div>
    </div>
</div>

CSS

.listing .row {
    margin-bottom: 20px;
}

.listing .row:last-child {
    margin-bottom: 0;
}
ajmedway
  • 1,492
  • 14
  • 28
0
    <div class="row">
<?php
    foreach ($rows as $row){
?> 
     <div class="col-lg-4 col-sm-4 col-6">
     Your content
     </div>
<?php } ?>
    </div>

This will give three columns in each row.

Robert
  • 21
  • 9
0

Simple And Easy Solution

    $array = array('0' => 'ABC', '1' => 'DEF', '2' => 'GHI', '3' => 'JKL', '4' => 'MNO', '5' => 'PQR', '6' => 'STU', '7' => 'VWX', '8' => 'YZ' );

    $index = 0;
    $n_array = array();
    foreach ($array as $key => $value) {
        if ($key % 3 == 0) {
            $index++;
        }
        $n_array[$index][] = $value;
    }
    foreach ($n_array as $key => $values) {
    ?>
        <div class="row">
            <?php 
                foreach ($values as $value) {
                    echo "<div class='col-md-4'>".$value."</div>";
                }
            ?>
        </div>
    <?php 
    }
0

Doing it with bootstrap in a twig file:

<div class="row">
    {% for item in items %}
        <div class="col-md-6 clearfix"></div>
    {% endfor %}
</div>
faye.babacar78
  • 774
  • 7
  • 12
0

In bootstrap 5 no need to write an extra loop

<div class="row gx-4 gx-lg-5 row-cols-2 row-cols-md-3 row-cols-xl-3 justify-content-center">
    <?php
    $categories = $response['data'];
    foreach ($categories as $key => $category) { ?>
        <div class="col mb-5">
            <div class="card h-100">
                <p><?= $category['title'] ?></p>
            </div>
        </div>
    <?php } ?>
</div>

it will break columns 3 per row on medium screen read more here: https://getbootstrap.com/docs/5.0/layout/grid/

Mahmood Hussain
  • 423
  • 5
  • 14