Using php to loop through and split items into uneven divs - php

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; ?>

Related

Running three iterations on a foreach loop

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>

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 logic to add a class to 2 rows every other 2 rows

Can anyone help me with the logic to add a class .col-md-offset-2 to every two rows in my code below...
<?php while(have_rows('report_quotes')): the_row(); ?>
<div class="col-md-12 <?php // help me ?>">
<?php /* quote */ ?>
<?php Post::get_template_part('sections/quote'); ?>
</div>
<?php endwhile; ?>
So the output will look like this...
<div class="col-md-12">...</div>
<div class="col-md-12">...</div>
<div class="col-md-12 col-md-offset-2">...</div>
<div class="col-md-12 col-md-offset-2">...</div>
<div class="col-md-12">...</div>
<div class="col-md-12">...</div>
<div class="col-md-12 col-md-offset-2">...</div>
<div class="col-md-12 col-md-offset-2">...</div>
<div class="col-md-12">...</div>
<div class="col-md-12">...</div>
<div class="col-md-12 col-md-offset-2">...</div>
<div class="col-md-12 col-md-offset-2">...</div>
...
Can anyone help?
Thanks
You can do this by using the modulus operator (%)
<?php $i = 0; while($i < 6): ++$i; ?>
<div class="col-md-12 <?=in_array($i % 4, array (0,3)) ? 'col-md-offset-4' : null ?>">...</div>
<?php endwhile; ?>
So in your case -
<?php $i = 0; while(have_rows()): the_row(); ++$i; ?>
<div class="col-md-12 <?=in_array($i % 4, array (0,3)) ? 'col-md-offset-4' : null ?>">
<?php /* quote */ ?>
<?php Post::get_template_part('sections/quote'); ?>
</div>
<?php endwhile; ?>
This essentially gets the remainder for each increment and in our case we know that if the remainder is 0 (divisible by 4) or a 3, then it should be indented.
Add a pointer that keeps track of the current loop index, and check if it the 3th or the 4th one in an iteration with the modulo operator.
Like this:
<?php
$i = -1;
while(have_rows('report_quotes')): the_row();
$i++;
?>
<div class="col-md-12
<?php if ( ($i % 4) == 2 || ($i % 4) == 3 ) { echo 'col-md-offset-2'; } ?> ">
<?php /* quote */ ?>
<?php Post::get_template_part('sections/quote'); ?>
</div>
<?php endwhile; ?>
Add a counter to know which row of the array you're in and use modulo:
<?php
$i = 0;
while(have_rows('report_quotes')): the_row(); ?>
<div class="col-md-12 <?php if (($i%4==2)||($i%4==3) {echo ' col-md-offset-2'; } ?> ?>">
<?php Post::get_template_part('sections/quote'); ?>
</div>
<?php endwhile; ?>

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.

While loop problem in PHP

I have my markup structure as below:
<div>
<div>value1</div>
<div>value2</div>
<div>value3</div>
<div>value4</div>
<div class="clear"></div>
</div>
<div>
<div>value5</div>
<div>value6</div>
<div>value7</div>
<div>value8</div>
<div class="clear"></div>
</div>
I have my data in a PHP result set, let's say I have 9 records so the structure should be as below:
<div>
<div>value1</div>
<div>value2</div>
<div>value3</div>
<div>value4</div>
<div class="clear"></div>
</div>
<div>
<div>value5</div>
<div>value6</div>
<div>value7</div>
<div>value8</div>
<div class="clear"></div>
</div>
<div>
<div>value9</div>
<div class="clear"></div>
</div>
So, the while loop should run in a way so that it will print the parent div after 4 records printed successfully. But in above I have 9 records so it should close the dive if its the last record.
Please help, Thanks!
The preconfig...
<?php
$num_of_results = sizeof($your_array);
$loops = ceil($num_of_results/4);
$k = 0;
?>
In your web
<?php for($p = 0; $p < $loops; $p++) { ?>
<div>
<div>
<?php for($i = 0; $i < 4 && $k < $num_of_results; $i++) { ?>
<div><?php echo $your_array[$k]; $k++;?></div>
<?php } ?>
<div class="clear"></div>
</div>
</div>
<?php } ?>
That's your problem isnt it?
By getting some idea from logic given here I tried following and it works.
<div> <!-- started main div -->
<?php
$icount = 1;
$itotal = mysql_num_rows($result_rs);
while ($rs = mysql_fetch_array($result_rs)) {
echo '<div>'.$rs['value'].'</div>';
if ($icount % 4 == 0 && $icount != $itotal){
echo '<div class="clear"></div>';
echo '</div>'; //closed main div
echo '<div>'; //started new main div
}
$icount++;
}
?>
</div> <!-- closed main div -->
That, solved my problem.
Edited: added itotal condition, so when you will have only 4 records per page then also this will work properly.
Right, now I know what you're after. I've done this before when showing items in a grid and you need to break each row because of that browser.
Anyway, it's ugly but I don't think it gets any easier than this
<?php for ($i = 0, $total = count($resultSet); $i < $total; $i += 4) : ?>
<div>
<?php
for ($j = $i; $j < ($i + 4); $j++) :
if (!isset($resultSet[$j])) :
?>
<div class="clear"></div>
</div>
<?php break 2; endif ?>
<div><?php echo htmlspecialchars($resultSet[$j]) ?></div>
<?php endfor ?>
<div class="clear"></div>
</div>
<?php endfor ?>
<div>
<?php for ($i = 1; $i <= 9; $i++): ?>
<?php if ($i%4 == 1 && $i != 1): ?>
<div class="clear"></div>
</div>
<div>
<?php endif; //$i%4 == 1 && $i != 1 ?>
<div>Value <?php echo $i ?></div>
<?php endfor; //$i = 1; $i <= 9; $i++ ?>
<div class="clear"></div>
</div>
or with an array:
<div>
<?php foreach ($arr as $k=>$v): ?>
<?php if (($k+1)%4 == 1 && $k != 0): ?>
<div class="clear"></div>
</div>
<div>
<?php endif; //($k+1)%4 == 1 && $k != 0 ?>
<div><?php echo $v ?></div>
<?php endforeach; //$arr as $k=>$v ?>
<div class="clear"></div>
</div>
or with a mysqli resultset:
<div>
<?php $count = 1 ?>
<?php while ($row = mysqli_fetch_array($result)): ?>
<?php if ($count%4 == 1 && $count != 1): ?>
<div class="clear"></div>
</div>
<div>
<?php endif; //$count%4 == 1 && $count != 1 ?>
<div><?php echo $row['value'] ?></div>
<?php $count++ ?>
<?php endwhile; ?>
<div class="clear"></div>
</div>
Why not use modulo to "close" a div?
<div>
<?php foreach($data as $key => $value) : ?>
<div><?php echo $value ?></div>
<?php if($key % 4 == 0 && $key != 0) : // add a clearing div, close the first group and open another one ?>
<div class="clear"></div>
</div>
<div>
<? endforeach ?>
<?php if($key % 4 != 0) : // div has not been closed as the number of records % 4 was not equal 0 ?>
<div class="clear"></div>
</div>
<? endif ?>

Categories