Running three iterations on a foreach loop - php

I am running a listing on a page in a row with three columns each. Each column requires different classes, I need to find a way to return these classes in a foreach loop to achieve the following ...
<div class="row">
<div class="box_skin1">...</div>
<div class="box_skin2">...</div>
<div class="box_skin3">...</div>
<div class="box_skin1">...</div>
<div class="box_skin2">...</div>
<div class="box_skin3">...</div>
</div>
I am currently using the following for alternating rows but now need to add a third ... how do I do that?
<?php $counter = 1; ?>
<div class="row">
<?php foreach ($newsRecords as $record): ?>
<?php if($counter % 2) : ?>
<!-- ROW 1 -->
<div class="box_skin1">...</div>
<?php else : ?>
<!-- ROW 2 -->
<div class="box_skin2">...</div>
<?php endif; ?>
<?php $counter++; ?>
<?php endforeach ?>
</div>

This should work
EDITED
<?php $counter = 1; ?>
<div class="row">
<?php foreach ($newsRecords as $record): ?>
<?php if($counter % 3 == 0) : ?>
<!-- ROW 3 -->
<div class="box_skin3">...</div>
<?php elseif ($counter % 3 == 2) : ?>
<!-- ROW 2 -->
<div class="box_skin2">...</div>
<?php elseif ($counter % 3 == 1): ?>
<!-- ROW 1 -->
<div class="box_skin1">...</div>
<?php endif; ?>
<?php $counter++; ?>
<?php endforeach ?>
</div>

IF-ELSE free structure. If you plan to add new div then you dont have to add new else-if condition just you need to increase counter size and it will work.
<?php $counter = 1; ?>
<div class="row">
<?php foreach ($newsRecords as $record): ?>
<div class="box_skin<?php echo $counter; ?>">...</div>
<?php
$counter++;
if ($counter >= 3) {
$counter = 1;
}
?>
<?php endforeach ?>
</div>

Related

Change column size based on amount of elements

So I'm working on a HTML carousel using Twitter Bootstrap, Wordpress and ACF Fields.
This carousel shows 2 items per row. Each of these items has a class of "col-md-6". So by showing 2 items per row, the total is 2 columns of "col-md-6" (which is perfect since this completes the 12 columns required by Bootstrap):
Here is my code:
<?php if (have_rows('columns_carousel_slide')) {
$count = 0; ?>
<div class="item active"><div class="row">
<?php while(have_rows('columns_carousel_slide')) {
the_row();
if ($count > 0 && (($count % 2) == 0)) {
?>
</div> <!--.item -->
</div> <!--.row -->
<div class="item">
<div class="row">
<?php } ?>
<div class="col-md-6">
<h2><?php the_sub_field('columns_carousel_slide_title'); ?></h2>
</div> <!--.col-md-6 -->
<?php $count++; } ?>
</div> <!--.item -->
</div> <!--.row -->
<?php } ?>
However, I would like to know if there's a way to detect if there's 1 item per row and if so, then show a "col-md-12" instead of a "col-md-6" in order to fill in the remaining space of not having 2 items.
Any ideas are welcome.
Thanks!
--
Edit: As suggested by Jakub, I've updated my code to the following:
<?php if (have_rows('columns_carousel_slide')) {
$count = 0; ?>
<div class="item active"><div class="row">
<?php
$multiplier = 1; //that could actually go before the while
if (count(get_field('columns_carousel_slide'))%2 === 1 &&
$count === count(get_field('columns_carousel_slide'))-1) {
$multiplier = 2;
} ?>
<?php while(have_rows('columns_carousel_slide')) {
the_row();
if ($count > 0 && (($count % 2) == 0)) {
?>
</div> <!--.item -->
</div> <!--.row -->
<div class="item">
<div class="row">
<?php } ?>
<div class="col-md-<?php echo (6*$multiplier);?>">
<h2><?php the_sub_field('columns_carousel_slide_title'); ?></h2>
</div> <!--.col-md-6 -->
<?php $count++; } ?>
</div> <!--.item -->
</div> <!--.row -->
<?php } ?>
However, I think I've must have missed something because I am getting total of "col-md-12" for all the rows.
Assuming that "get_field" returns the array with all rows, then you would need to change the following:
<div class="col-md-6">
<h2><?php the_sub_field('columns_carousel_slide_title'); ?></h2>
</div> <!--.col-md-6 -->
with this:
<?php
$multiplier = 1; //that could actually go before the while
if (count(get_field('columns_carousel_slide'))%2 === 1 &&
$count === count(get_field('columns_carousel_slide'))-1) {
$multiplier = 2;
} ?>
<div class="col-md-<?php echo (6*$multiplier);?>">
<h2><?php the_sub_field('columns_carousel_slide_title'); ?></h2>
</div> <!--.col-md-12 -->
A short explanation:
initially we set the multiplier to 1 (so that 6*1 = 6 for paired
columns).
we do a condition to check if number of items is even
and we are currently processing the last item. If so - we set the
multiplier to 2 (so that 6*2 = 12 for single column)
we set the class to be "col-md-" and the result of our calculation (either 6 or 12)

PHP Product Listing - End of Loop Close Row

Sorry for the title, I wasn't sure how to word it.
Basically, I have a webpage that uses Advanced Custom Fields to populate products, it loops through the products and displays them in groups of three, per row; each row alternates color - light grey to dark grey.
My issue is, the code I wrote is checking if each row has 3 items, so if the product listing row ends on 1 or 2, the row containing div is not closed off, thus wrapping my footer and messing up the for the rest of the page. The following is my code, it should be pretty easy to follow - you can also see I am using LazyLoadAny - Basically, I count the items, if there are more than 6 I lazyload the rest. On the first item I open the row container and when there are three I close it. So again, I need to figure out how to close the container if the row ends on 1 or 2 items not just 3.
Short Version: How do I close the "internal-product-light" or "internal-product-dark" rows if they end with 1 or 2 products instead of 3?
<?php
$count = 0;
$rowCount = 0;
$rowClass = "internal-product-light";
// check if the repeater field has rows of data
if( have_rows('product_listing_repeater') ): ?>
<div class="internal-container">
<div class="full-product-line-contain">
<?php // loop through the rows of data
while ( have_rows('product_listing_repeater') ) : the_row(); $count++; $rowCount++; ?>
<?php if($rowCount == 1) { ?>
<div class="<?php echo $rowClass; ?>">
<div class="product-centering">
<?php if($count > 6) { ?>
<div class="js-lazyload">
<?php echo "<!--"; }
} ?>
<div class="internal-section product-line-item product-alignment clearfix">
<div class="product-contain">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link">
<?php
if(get_sub_field('has_image')):
$singleImage = get_sub_field('block_image');
?>
<img class="product-line-image" src="<?php echo $singleImage ?>" />
<?php endif; ?>
</a>
<?php endif; ?>
<div class="internal-content-contain-right no-float">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link-title">
<h2><?php the_sub_field('block_headline'); ?></h2>
</a>
<?php endif; ?>
<?php if(get_sub_field('has_link')): ?>
<?php the_sub_field('link_text')?>
<?php endif; ?>
</div>
</div>
</div>
<?php if($rowCount == 3) { ?>
<?php if($count > 6) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php $rowCount = 0;
if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
<?php endwhile; ?>
</div>
</div>
Your last if-statment could be:
<?php if(($rowCount % 3) == 0) { ?>
<?php if($count > 6) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
And then, after the while-block:
<?php if(($rowCount % 3) <> 0) { ?>
<?php if($count > 6) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
The x % y returns the remainder of x/y.
So the following code is actually a much simpler solution than I thought it would be - I will post the code then break it down.
<?php
$count = 0;
$rowCount = 0;
$rowClass = "internal-product-light";
$rowInfo = get_sub_field('product_listing_repeater');
$fieldCount = count($rowInfo);
// check if the repeater field has rows of data
if( have_rows('product_listing_repeater') ): ?>
<div class="internal-container">
<div class="full-product-line-contain">
<?php // loop through the rows of data
while ( have_rows('product_listing_repeater') ) : the_row(); $count++; $rowCount++; ?>
<?php
if($rowCount == 1) { ?>
<div class="<?php echo $rowClass; ?>">
<div class="product-centering">
<?php if($count > 6) { ?>
<div class="js-lazyload">
<?php echo "<!--"; }
} ?>
<div class="internal-section product-line-item product-alignment clearfix">
<div class="product-contain">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link">
<?php
if(get_sub_field('has_image')):
$singleImage = get_sub_field('block_image');
?>
<img class="product-line-image" src="<?php echo $singleImage ?>" />
<?php endif; ?>
</a>
<?php endif; ?>
<div class="internal-content-contain-right no-float">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link-title">
<h2><?php the_sub_field('block_headline'); ?></h2>
</a>
<?php endif; ?>
<?php if(get_sub_field('has_link')): ?>
<?php the_sub_field('link_text')?>
<?php endif; ?>
</div>
</div>
</div>
<?php if($rowCount == 3 || $count == $fieldCount) { ?>
<?php if($count > 6 || $count == $fieldCount) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php $rowCount = 0;
if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
<?php endwhile; ?>
</div>
</div>
As you can see, I added the variable $fieldCount = count($rowInfo) which counts the ACF repeater field. Then when I was originally checking for 3 products, I added an OR statement - <?php if($rowCount == 3 || $count == $fieldCount) { ?> and to the lazyload check - <?php if($count > 6 || $count == $fieldCount) { echo "-->"; ?>
This makes sure that if it is 3, it closes the div and if it is the end of the array (figured out through count), it closes the div.
Please post any questions for clarification.

Using php to loop through and split items into uneven divs

Looping through 12 items I would like to separate the whole list into divs so that 0,1 are in a div, 2 in a div, 3,4 in a div, 5 in a div and so on..
<!-- half half 0,1 -->
<div class="right-grid-row">
<div class="medium-6 columns">
0
</div>
<div class="medium-6 columns">
1
</div>
</div>
<!-- full 2 -->
<div class="right-grid-row">
<div class="medium-12 columns">
2
</div>
</div>
<!-- half half 3,4 -->
<div class="right-grid-row">
<div class="medium-6 columns">
3
</div>
<div class="medium-6 columns">
4
</div>
</div>
<!-- full 5 -->
<div class="right-grid-row">
<div class="medium-12 columns">
5
</div>
</div>
I assume modulus is needed on the multiple loops but I'm struggling a little bit.
Notes**
<?php for($i = 0; $i < 12; $i++): ?>
<?php echo $i; ?>
<?php endfor; ?>
Thanks,
You could use the modulus operator, but here's another way you could do it:
$counter = 1;
for($i = 0; $i < 12; $i++) {
... // create inner div
if ($counter == 2)
echo '</div><div class="medium-12 columns">';
else if ($counter == 3) {
echo '</div><div class="right-grid-row">';
$counter = 0; // reset the counter
}
$counter++;
}
It's simple and relatively easy to read. This code is not complete, you would need to handle your first opening opening and last closing divs, but hopefully you get the idea.
<?php for($i = 0; $i < 12; $i++): ?>
<?php switch($i) { ?>
<?php case '0': ?>
<?php case '1': ?>
<?php case '3': ?>
<?php case '4': // add more if needed ?>
<?php //your code ?>
<?php break; ?>
<?php default: ?>
<?php //your other code ?>
<?php } ?>
<?php endfor; ?>

PHP foreach loop, every amount of steps create new wrapper outside loop

I need some advice on this one. If I have a PHP foreach loop:
<div class="wrapper">
<?php foreach ($item as $element): ?>
<!-- some HTML of $element -->
<?php endforeach; ?>
</div>
and after every 5th $item I want to create a new .wrapper with the next 5 items in the foreach. And redo this step until all are through.
The output should be like:
<div class="wrapper">
<!-- some HTML of $element 1 -->
<!-- some HTML of $element 2 -->
<!-- to $element 5 -->
</div>
<div class="wrapper">
<!-- some HTML of $element 6 -->
<!-- to $element 10 -->
</div>
Do I need to run another foreach outside to make this possible?
Thanks
Try this
$i = 0;
<?php
foreach ($item as $element) {
if($i%5==0) echo "<div class=\"wrapper\">";
?>
<!-- some HTML of $element -->
<?php
if($i%5==4) echo "</div>";
$i++;
}
?>
Possible solution:
<div class="wrapper">
<?php $counter = 0; ?>
<?php foreach ($item as $element): $counter++; ?>
<!-- some HTML of $element -->
<?php if ($counter % 5 === 0 && $counter !== count($item)): ?>
</div>
<div class="wrapper">
<?php endif; ?>
<?php endforeach; ?>
</div>
Try this
$i = 0;
<?php foreach($item as $element) : ?>
<?php if($i == 0) : $i=5; ?>
<div class="wrapper">
<?php endif; ?>
<!-- some HTML of $element -->
<?php $i -= 1; if($i == 0) : ?>
</div>
<?php endif; ?>
<?php endforeach; ?>

Place DIV's in a containing DIV based on a numeric value

Ive got the follow PHP:
<div class="slide-background">
<div class="slide">
<?php foreach (array_chunk($items->submenu, $linkCount) as $items): ?>
<?php if (12 / $cols == 1):?>
<div class="col-md-12">
<?php else: ?>
<div class="col-md-<?php echo 12 / $cols; ?>">
<?php endif; ?>
<ul>
<?php foreach($items as $submenu): ?>
<?php echo $submenu; ?>
<?php endforeach; ?>
</ul>
</div>
<?php endforeach; ?>
</div>
<ul class="pager">
<li>prev</li>
<li>next</li>
</ul>
</div>
</div>
basically it calculates how many links to display and how many columns, but i now need to place the links in <div class="slide"></div>, but based on the columns.. so basically i need to say if $cols = 2 place two div's in a div and close.. so its basically how many every $cols it should place so many div's in that div..
Its Confusing for me to even explain.. I think Ive explained it rather well above.. If not place say so and ill try again..
Any Help Greatly Appreciated..
UPDATE:
thanks to Hans ive now have the following:
<?php $linksPerColumn = ceil($linkCount / $cols); $linkCounter = 0;?>
<div class="slide-background">
<div class="slide">
<div class="col-md-<?php echo 12 / $cols ?>">
<ul>
<?php foreach ($items->submenu as $link): ?>
<?php $linkCounter++;?>
<?php if($linkCounter % $linksPerColumn == 0):?>
</ul>
</div>
<div class="col-md-<?php echo 12 / $cols ?>">
<ul>
<?php endif; ?>
<?php echo $link; ?>
<?php endforeach; ?>
</ul>
</div>
</div>
<ul class="pager">
<li>prev</li>
<li>next</li>
</ul>
</div>
</div>
only problem is when there's only one column and i need 2 links and then for it to close the div and the ul and start new ones.. right now it does that except for everyone and not for every two links...
You could use modulus for this one. You should calculate how many items you need per column. And then create a close and open div for example:
<?
$linksPerColumn = 4;
if ($linkCount > 4){
$linksPerColumn = ceil ($linkCount / $amountOfColums);
}
$linkCounter = 0;
?>
<div class="slide-background">
<div class="slide">
<?
foreach ($links as $link)
{
$linkCounter++;
?>
// Do your HTML Here.
<?
if($linkCounter % $linksPerColumn = 0)
{
?>
</div>
<div class="slide">
<?
}
?>
</div>
</div>
// Rest of the HTML here.
I think this should do the trick for you.

Categories