Foreach loop: split elements in groups of five and six - php

I'm using a foreach loop to output images fetched from the Instagram API.
I want to split the outputted images in groups of four and five and in addition to that add a div element to each group except the last one where 2 div's should be added, so I get the following structure:
<div class="group>
<div class="extra"> </div>
<img/>
<img/>
<img/>
<img/>
</div> <!-- Close group of 5 -->
<div class="group>
<div class="extra"> </div>
<img/>
<img/>
<img/>
<img/>
<img/>
</div> <!-- Close group of 6 -->
<div class="group>
<div class="extra"> </div>
<img/>
<img/>
<img/>
<div class="extra"> </div>
</div> <!-- Close group of 5 -->
By using modulus in the loop I've manage to group the elements with the correct number of items in each group, but when I try to add the extra div to each group it breaks the counting and I'm no longer getting the correct number of elements grouped together. The code I'm currently using to print out the images (12 in total):
<div class="group"> <!-- Open group-wrapper -->
$count = 0;
foreach($decoded_results['data'] as $item) {
if ($count % 11 == 0 || $count % 11 == 5 ) {
echo '<div class="extra"> </div>';
echo '</div> <div class="group">';
}
echo '<a target="_blank" href=' .$link_url. '>';
echo '<div class="img-wrapper">';
echo '<img src="'.$image_link.'" /> </div> </a>';
$count++;
}
Any suggestion how this can be achieved?

This will be enough to point you in the correct direction:
<div class='group'>
<div class='extra'></div>
<?php
$i = 1;
$j = 1;
$step = 4;
$count = count($decoded_results['data']);
foreach($decoded_results['data'] as $k => $v) {
?>
<a target='_blank' href='<?php echo $v;?>'>
<div class='img-wrapper'>
<img src='<?php echo $v;?>' />
</div>
</a>
<?php
if (($j % $step) == 0 && $i < $count) {
?>
</div>
<div class='group'>
<div class="extra"></div>
<?php
$step = ($step == 4) ? 5: 4;
$j = 0;
}
$j++;
$i++;
}
?>
<div class='extra'></div>
</div>
On a side note you should be aware that having a div (block element) inside an a (inline element) isn't exactly semantic HTML, but still widely accepted nowadays. I personally tend to avoid this and can do by using CSS.

If you're using PHP use the array_chunk() function
http://php.net/manual/en/function.array-chunk.php

Related

Output foreach-item in <div>, but output every 2nd and 3rd item in wrapping div

I have an array with items: $array = ['item 1','item 2','item 3','item 4','item 5','item 6','item 7']
I am looking for the following HTML:
<div class="big">Item 1</div>
<div>
<div class="small">Item 2</div>
<div class="small">Item 3</div>
</div>
<div class="big">Item 4</div>
<div>
<div class="small">Item 5</div>
<div class="small">Item 6</div>
</div>
<div class="big">Item 7</div>
In text: Every 3rd item (including the first) have to have their own div, while the 2nd and 3rd items get a wrapping div.
I've come up with the following loop, but I'm pretty sure it's not going to work in the long run, since it'll probably end the loop with an opening div, since I keep on opening a new one after each BIG ITEM.
$i = 0;
foreach($array as $item) {
<?php
if($i % 3 == 0) {
if($i == 0) {?>
<div class="big">
Item <?= $i; ?>
</div>
<div>
<?php } else { ?>
</div>
<div class="big">
Item <?= $i; ?>
</div>
<div>
<?php } ?>
<?php } else { ?>
<div class="small">
small item
<?= $i; ?>
</div>
<?php } ?>
<?php
$i++;
}
I feel like I'm close, but it also feels wrong to start and close divs in $is where it doesn't belong. Maybe the only thing I'm missing is checking if $i equals the length of the array, and then don't open a new <div> after a big item?
You can use simple if-elseif-else construct to print the divs.
If the index of the current element % 3 is 0, it is a big div, else it is a small div.
If the index of the current element % 3 is greater than 0, it is a small div.
If it is 1, prepend an opening div tag.
If it is 2, append a closing div tag.
Snippet:
<?php
foreach ($array as $idx => $set) {
$mod = $idx % 3;
if($mod === 0){
echo "<div class='big'>$set</div>";
}elseif($mod === 1){
echo "<div><div class='small'>$set</div>";
}else{// if $mod is 2
echo "<div class='small'>$set</div></div>";
}
}
Online Demo
Alternatively, use array_chunk then pick out the first item with array_shift, then join the remaining.
<?php
$array = array_chunk(['item 1','item 2','item 3','item 4','item 5','item 6','item 7'], 3);
foreach ($array as $set) {
echo '<div class="big">'.array_shift($set).'</div>';
if (count($set)) echo '<div><div class="small">'.implode('</div><div class="small">', $set).'</div></div>';
}
?>
Result
<div class="big">item 1</div>
<div>
<div class="small">item 2</div>
<div class="small">item 3</div>
</div>
<div class="big">item 4</div>
<div>
<div class="small">item 5</div>
<div class="small">item 6</div>
</div>
<div class="big">item 7</div>
Example: https://3v4l.org/URB3D
Here you are my simple answer: I think you don't need to use additional counter in case that interpreter adds indexes to array:
$array = ['item 1','item 2','item 3','item 4','item 5','item 6','item 7'];
foreach($array as $key=>$da){
$a = $key % 3;
if($a === 0){
echo "<div class=\"big\">" . $da . "</div>\n";
}
else{
if($a === 1)
echo "<div>\n";
echo " <div class=\"small\">" . $da . "</div>\n";
if($a === 2)
echo "<div>\n";
}
}

Always show specific result at the end of a for each loop

I got a project page that echoes multiple projects in a foreach loop, and every 4 results it starts a new row on the page.
However I got an element that always needs to be shown as the last result. How can I achieve that?
My foreach loop:
<?
$tel = 1;
foreach ($projectcr as $project) {
$article_images = $project['images']; // Get image parameters of the article
$pictures = json_decode($article_images); // Split the parameters apart
$introtext = $project['introtext'];
if ($project['title'] != '') {
if($tel == 1) {
echo '<div class="row">';
}
echo '
<div class="col-xs-12 col-sm-6 col-lg-3 js-wpg-item" data-categories="gardening">
<a class="card portfolio-grid__card js-wpg-card" href="project/'.$project['alias'].'.html">
<img src="cms/'.$pictures->{'image_intro'}.'" class="card-img-top portfolio-grid__card-img wp-post-image" alt="19" height="240" width="360">
<div class="card-block portfolio-grid__card-block">
<h5>'.$project['title'].'</h5>
<p>'.$project['created'].'</p>
</div>
</a>
</div>'
;
if(($tel % 4) == 0){
echo '</div> <div class="row">';
}
$tel++;
}
}
if(($tel % 4) != 0){
echo '</div>';
}
?>
The element I want to be shown as last block:
<div class="row">
<div class="col-xs-12 col-sm-6 col-lg-3 js-wpg-item" data-categories="">
<div class="portfolio-grid__card portfolio-grid__card--dummy js-wpg-card" href="projects/">
<div class="portfolio-grid__card-block text-center">
<span class="fa fa-cloud-upload fa-2x"></span>
<h5>Uw volgende project hier?</h5>
<p class="portfolio-grid__card-text">
NEEM CONTACT OP
</p>
</div>
</div>
</div><!-- /.col -->
</div><!-- /.row -->
This has the following result:
The element is now shown outside the row, while I need it to be inside the row (but only the last one).
Change your last if condition just after ending foreach
if(($tel % 4) != 0){
//echo div.col-... inside .row started in loop
echo '<div class="col-xs-12 col-sm-6 col-lg-3">always to be shown at last</div>';
//end .row
echo '</div>';
}
Add the content you want to show at the end of the loop. Don't check the condition and add the closing tag for row div, because it will fail to add the close tag if modulus of $tel is equal to zero. Your last content should be shown in new row but it will not close the tag.
$last = <div class="col-xs-12 col-sm-6 col-lg-3 js-wpg-item" data-categories="">
<div class="portfolio-grid__card portfolio-grid__card--dummy js-wpg-card" href="projects/">
<div class="portfolio-grid__card-block text-center">
<span class="fa fa-cloud-upload fa-2x"></span>
<h5>Uw volgende project hier?</h5>
<p class="portfolio-grid__card-text">
NEEM CONTACT OP
</p>
</div>
</div>
</div>
foreach($projectcr as $project) {
...//your code
...
}
echo $last. '</div>';
There are multiple ways to achieve that but can't you just add a element to your array?
$p = [];
$p['title'] = 'Uw volgende project hier?';
$p['created'] = 'NEEM CONTACT OP'
array_push($projectcr, $p);
A other way to do it is to check if its the last element in the array
$lastElement = end($array);
// you code
if($project == $lastElement){
//add the static block
}

How can I display a two column array in PHP/HTML?

I have an array of icons. Right now, we only display them in buckets of 4. So if you have 7 icons, the 4th icon on the first slide will repeat as the 8th on the second slide. That's because the 3rd index of the array is stored in that same spot. To fix this, I want to loop through the array instead of explicitly iterating icon by icon.
<?php if (!empty($icons)) { // if we have icons attributes
// NOTE: we've changed it to show as many sets as we can
// (sets of 4)
$number_of_sets = ceil(count($icons) / 4);
$k=0; // for inner iteration
for ($j=0;$j < $number_of_sets; $j++) {
$slide_total ++;
?>
<div class="cf slide icon-slide">
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon1 = $icons[$k];
$k++;
}
?>
<div class="col left">
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon1['thumb']?>" alt="<?=htmlentities($icon1['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon1['post_title']?></h4>
<p><?=$icon1['post_content']?></p>
</div>
</div>
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon2 = $icons[$k];
$k++;
}
?>
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon2['thumb']?>" alt="<?=htmlentities($icon2['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon2['post_title']?></h4>
<p><?=$icon2['post_content']?></p>
</div>
</div>
</div>
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon3 = $icons[$k];
$k++;
}
?>
<div class="colR right">
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon3['thumb']?>" alt="<?=htmlentities($icon3['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon3['post_title']?></h4>
<p><?=$icon3['post_content']?></p>
</div>
</div>
<?php
// up to 4 icons
if (is_array($icons) && !empty($icons[$k])) {
$icon4 = $icons[$k];
$k++;
}
?>
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon4['thumb']?>" alt="<?=htmlentities($icon4['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon4['post_title']?></h4>
<p><?=$icon4['post_content']?></p>
</div>
</div>
</div>
</div> <!-- // end icon slide -->
<?php
} // end for $j (number of sets of 4 icons
?>
My proposed solution:
<?php if (!empty($icons)) {
$num_cols = 2;
$i = 0;
$slide_items = 4;
?>
<div class="cf slide icon-slide">
<?php foreach ( $icons as $icon ) {
echo $i++%$num_cols==0 ? '</div><div class="col" style="width: 250px;">' : '';
?>
<div class="cf icon">
<div class="col thumb">
<img src="<?=$icon['thumb']?>" alt="<?=htmlentities($icon['post_title'])?>" />
</div>
<div class="colR details">
<h4><?=$icon['post_title']?></h4>
<p><?=$icon['post_content']?></p>
</div>
</div>
<?php } } // end if we have icons attributes ?>
I'm having trouble figuring out how to make another slide after I hit 4 icons. Adding the following line before the end of the foreach loop hasn't worked.
echo $i++%$slide_items==0 ? '</div><div class="cf slide icon-slide">' : '';
Here's some logic for the loop:
$i = count( $icons );
if ( $i % 4 != 0 )
$i = $i + ( $i % 4 );
for( $n = 0; $n < $i; $n++ )
{
if ( $n % 4 == 0 )
{
// code to open a row here
}
// code to open a column here
// echo your icon here, use isset() or !empty().
// code to close a column here
if ( $n > 0 && $n % 3 == 0 )
{
// code to close a row here
}
}
The IFs at the top is for keeping the column number consistent. Otherwise there'll be some weirdness at the end of the loop.

PHP Iterate 12 items perform echo on every third

Hi I have been chasing my tail for a while on this one and wondered if someone could solve my headache.
Basically I am rendering 12 items to the page. Each 3 items need to be wrapped in a row like:
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
<div class='row'>
<div class='item'>
</div>
<div class='item'>
</div>
<div class='item'>
</div>
</div>
Thanks in advance.
Hi I think some code would help:
$i=0;
foreach($posts as $p) {
$i++
}
So basically within the for each I will be outputting a row and 3 items.The results are coming from a database query. I have tried a few different approaches such as
if($i == 1) {echo "<div class='row'>";}
if ($counter % 4 == 0) {
echo "</div><div class='row'>";
}
However I keep failing, please note these are just snippets of code.
You need to use two loops:
// Outer loop for each row
for ($row = 0; $row < 4; $row++) {
echo '<row>';
// Inner loop for the items
for ($item = 0; $item < 3; $item++) {
echo '<item>';
}
echo '</row>';
}
You should have done it yourself. it needs to know very basic of loop.
try like this:
for($i=0;$i <= 3; $i++){ //outer loop for 12 times
echo "<row>"; // start row
for ($j=0;$j<3;$j++){ // inner loops for echoing 3 times
echo "<item>"; //echo item
}
echo "</row>"; // end row
}
demo : https://eval.in/107129
I have used "\n" for new line in demo. if you needed new line then you can use <br />

Simple php logic

So I haven't programmed in a while, but i decided to tackle a small web app to get back in the game. Im having a bit of trouble though, and its kind of annoying because I know the answer is simple. So i'm making a databaseless image gallery, and i'm using Twitter Bootstrap as the front end. I want to display the images that i'm reading from a directory using the classic bootstrap row setup like this:
<div class="row">
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="http://placehold.it/750x450">
</div>
</div>
The problem is that I can only put four images into a row so I cant just do something like:
<div class="row">
<?php echo"$img";?>
</div>
How can I echo a
<div class="row">
every four
<?php echo"$img";?>
I feel like a nested loop may work, but i just cant seem to get it.
Thanks.
You need a loop with an index; then you can check if the index is divisible by 4:
if ($i % 4 == 0) {
?><div class="row"></div><?php
}
Alternately, you can array_chunk your data, and run a nested loop on the results, outputting the row in the outer loop.
For each row
for($i=0; $i<$num_item; $i++) {
Start a new row before the first item and every 4th item following
if($i % 4 == 0) {
echo '<div class="row">';
}
End a row after the 4th item and every 4th item following
if($i % 4 == 3) {
echo '</div>
}
Full code:
for($i=0; $i<$num_item; $i++) {
if($i % 4 == 0) {
echo '<div class="row">';
}
// Print the item here
if($i % 4 == 3) {
echo '</div>
}
}
When dealing with a lot of html code using the (notice the colon and endif)
<?php for (index; condition; step) : ?>
<h1>HTML STUFF</h1>
<?php endif; ?>
alternative syntax is a bit cleaner than the conventional markup.
I would suggest:
<div class="row">
<?php for($i = 0; $i < $total_pics; $i++): ?>
<div class="col-md-3 portfolio-item">
<img class="img-responsive" src="<?php echo $img_link; ?>">
</div>
<?php if ($i % 4 == 3 && $i < $total_pics): ?>
</div>
<div class="row">
<?php endif;
endfor; ?>
</div>
This allows the new row only to be put in place if there are more pictures to show and after the fourth one only.
This allows the html code to be indented as you want and clean the php code up a bit in the process. This also allows the initial row to be self closing if there are no pictures to show.

Categories