I'm working on a Mega Menu for WooCommerce Product Category. I'm able to get the list of all Subcategories using the code below;
$parent_id = 37; //ID of the Parent Category
$subCat_of_parent = get_terms('product_cat',array('child_of' => $parent_id));
Then used in a html structure as below;
<div class="row">
<div class="col-md-6">
<ul>
<?php
foreach ($subCat_of_parent as $subcat) {
?>
<li>
<?php echo $subcat->name; ?>
</li>
<?php
}
?>
</ul>
</div>
</div>
This worked by getting all the list of subcategory of the parent category in this format;
<div class="row">
<div class="col-md-6">
<ul>
<li><a>1st subcategory</a></li>
<li><a>2nd subcategory</a></li>
<li><a>3rd subcategory</a></li>
<li><a>4th subcategory</a></li>
<li><a>5th subcategory</a></li>
<li><a>6th subcategory</a></li>
</ul>
<div>
</div>
what i want to achieve is after the 3rd subcategory, it should break and continue on a new column, so that i can get something like this;
<div class="row">
<div class="col-md-6">
<ul>
<li><a>1st subcategory</a></li>
<li><a>2nd subcategory</a></li>
<li><a>3rd subcategory</a></li>
</ul>
<div>
<div class="col-md-6">
<ul>
<li><a>4th subcategory</a></li>
<li><a>5th subcategory</a></li>
<li><a>6th subcategory</a></li>
</ul>
<div>
</div>
How can i achieve this? Thanks for your help in advance
You can use array_chunk() to divide the array into groups of 3.
<div class="row">
<?php
$chunks = array_chunk($subCat_of_parent, 3);
foreach ($chunks as $group) {
print '<div class="col-md-6">';
print '<ul>';
foreach ($group as $subcat) {
print '<li>';
//to-do
print '</li>';
}
print '</ul>';
print '</div>';
}
?>
</div>
You need to emit the inner <div class="col-md-6"><ul> and the </ul></div> part every three categories.
Here is the pseudocode:
Emit <div class="row">
Set a counter, something like $i = 0
Start your for loop, foreach ($subCat_of_parent as $subcat) {
Now say if ($i == 0), emit the start div tag and start ul tag.
Emit your list item
$i = ($i + 1) % 3
Now say if ($i == 0), emit the close ul tag and close div tag.
If the number of subcategories is not a multiple of three, you need extra logic at the end to make sure the last group is properly closed off.
<?php
$arr = array(1, 2, 3, 4,5,6);
$count = 0;
?>
<div class="row">
<?php
foreach ($subCat_of_parent as $subcat)
{
// echo "count =".$count;
if($count%3 == 0)
{
echo ('<div class="col-md-6">
<ul>');
}
$count++;
?>
<li>
<?php echo $subcat->name; ?>
</li>
<?php
if($count%3 == 0)
{
echo ('
</ul></div>');
}
}
?>
</div>
Below code is working, You can use this.
<?php
$subCat_of_parent = array('1st sub', '2nd sub', '3rd sub', '4th sub', '5 sub', '6 sub', '7 sub');
$subCat_of_parent = array_chunk($subCat_of_parent, 3);
?>
<div class="row">
<?php
foreach ($subCat_of_parent as $subcats) {
?>
<div class="col-md-6">
<ul>
<?php
foreach ($subcats as $subcat) {
?>
<li><?php echo $subcat; ?></li>
<?php
}
?>
</ul>
</div>
<?php
}
?>
</div>
Related
I created a database with 5 categories and created a page to display the available categories that I pull from the database. The problem is that I have 4 divs that have the following class ( col-md-3 ) and one that is ( col-md-6 ).
Code for gathering the first 5 categories ( col-md-3 ):
<?php
$this->db->limit(4);
$categories = $this->db->get_where('category', array('parent' => 0))->result_array();
foreach ($categories as $key => $category):
?>
<div class="gallery-item">
<div class="grid-item-holder">
<div class="listing-item-grid">
<img src="<?php echo base_url('uploads/category_thumbnails/').$category['thumbnail'];?>" alt="" />
<div class="listing-counter">
<span>2</span>Locations
</div>
<div class="listing-item-cat">
<h3><?php echo $category['name']; ?></h3>
<p><?php echo $category['name']; ?></p>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
Code for gathering another 1 category ( col-md-6 ):
<?php
$this->db->limit(1);
$categories = $this->db->get_where('category', array('parent' => 0))->result_array();
foreach ($categories as $key => $category):
?>
<div class="gallery-item gallery-item-second">
<div class="grid-item-holder">
<div class="listing-item-grid">
<img src="<?php echo base_url('uploads/category_thumbnails/').$category['thumbnail'];?>" alt="" />
<div class="listing-counter">
<span>2</span>Locations
</div>
<div class="listing-item-cat">
<h3><?php echo $category['name']; ?></h3>
<p><?php echo $category['name']; ?></p>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
With this code, I get a display of categories but instead of displaying 5 categories, it repeats one of the displayed 4. How can I fix the code so that the display automatically continues to display the categories in all divs? If I forgot to write something, correct it or ask, I will update the question.
It looks like you are getting the first 4 items for the first foreach loop and then getting the first one again for the second loop. Would it make sense to get all 5 and process them in one single foreach loop only adding 'gallery-item-second' on the 5th item, something like ...
<?php
$this->db->limit(5);
$categories = $this->db->get_where('category', array('parent' => 0))->result_array();
$index = 0;
foreach ($categories as $key => $category):
$index++;
if ($index == 5) {
echo '<div class="gallery-item gallery-item-second">';
} else {
echo '<div class="gallery-item">';
}
?>
<div class="grid-item-holder">
. . .
</div>
</div>
<?php endforeach; ?>
Or if you must have the second loop then get 5 items and only show the 5th.
And to make sure you get the same 5 you could use a sort criteria when you get the items.
The problem is resolved with math:
I have added the next code:
...
$num = 5;
$i = 0;
foreach ($categories as $key => $category):
if ($i < ($num - 1)) {
// show div col-md-3
} else {
// show div col-md-6
}
endif;
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";
}
}
I need a little help with a php loop for OpenCart.
I need to do is wrap a div around the output of the data every 4 loops.
I have the following
<?php foreach ($categories as $category) { ?>
<div class="col-lg-3 col-md-3">.....</div>
<?php } ?>
I get this
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
But what I'm hoping to get is
<div class="row">
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
</div>
<div class="row">
<div class="col-lg-3 col-md-3">.....</div>
<div class="col-lg-3 col-md-3">.....</div>
</div>
Any help would be greatly appreciated :)
try this
<?php
$i=0;
$wrap_count = 4; // you can change this no of divs to wrap
foreach ($categories as $category)
{
$i+=1;
if($i%$wrap_count==1)
{
echo '<div class="row">';
}
?>
<div class="col-lg-3 col-md-3">.....</div>
<?php
if($i%$wrap_count==0)
{
echo '</div>';
}
}
if($i%$wrap_count!=0)
{
echo '</div>';
}
?>
<?php
$i = 0;
foreach ($categories as $category) {
if (($i % 4) === 0) {
echo "<div class='row'>";
}
echo '<div class="col-lg-3 col-md-3"></div>';
if (($i % 4) === 3) {
echo "</div>";
}
$i++;
}
?>
Ps, If $categories is a non keyed array, ie array('a', 'b', 'c') then you can get rid of the i = 0; and i++; and change the foreach to foreach ($categories as $i => $category) {
And as zerkms mentioned in a comment, the magic here is coming from % (Modulo operation), which is essentially like a clock- the numbers will increment from 0 upwards until they hit 12, at which point it is reset to 0 again. So the clock is said to be modulo twelve. In this instance we're using modulo four to cyclically print our our opening and closing row elements.
Modulo four would be the sequence 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, etc
Try this :-
<div class="row">
<?php
$i = 1;
foreach ($categories as $category) { ?>
<div class="col-lg-3 col-md-3">.....</div>
<?php if ($i % 4 == 0){ ?>
</div><div class="row">
<?php } ?>
<?php $i++; ?>
<?php } ?>
You may use a counter variable. Initially set it to equal 0. Then for each loop check its value. If it is equal to 0 then output <div class="row"> and add 1 to the variable's value. If its value is > 0 and < 5 then output <div class="col-lg-3 col-md-3">.....</div> and add 1 to it's value. If it is equal to 5 output </div> and reset the counter variable to 0.
Something like (code tested):
<?php
$counter = 0;
foreach ($categories as $category) {
If ($counter == 0) {
echo '<div class="row">
<div class="col-lg-3 col-md-3">.....</div>
';
$counter++;
} elseif ($counter > 0 && $counter < 3) {
echo '<div class="col-lg-3 col-md-3">.....</div>
';
$counter++;
} elseif ($counter == 3) {
echo '<div class="col-lg-3 col-md-3">.....</div>
</div>
';
$counter = 0;
}
}
if ($counter > 0) {
echo '</div>
';
}
?>
The Modulo operator will be equal to zero when used in a comparison with the number of items you would like in a row. So you can output your starting <div> there.
To add a closing div you will need to check the modulo of 4 is equal to 3 or if we have reached the total number of items, to prevent a missing close </div>.
<?php
// set a counter
$rowCount = 0;
// store the total number of categories minus 1 as we will be
// counting from 0 with the counter
$categoryTotal = count($categories) - 1;
foreach($categories as $c){
if($rowCount % 4 == 0){
echo '<div class="row">';
}?>
<div class="col-lg-3 col-md-3""></div>
<?php
// add your closing div if it is the end of a row or if there are no more items
if($rowCount % 4 == 3 || $rowCount == $categoryTotal){
echo '</div>';
}
// increment your counter
$rowCount++;
} ?>
I have an alternative option that might work depending on your array.
$new_array = array_chunk($your_array, 4);
foreach($new_array as $group_of_$four){
echo '<div class="row">';
foreach($group_of_four as $one){
// Single Item
}
echo '</div>';
}
Well, add this to your code:
//before foreach
$i = 0;
// inside the foreach before its closing }
$i++;
}//this closes the foreach
And then before adding any div (probably in the beginning of the foreach:
if($i % 4 == 0)
{
echo "<div class='each-four-iterations'>";
}
And before the $i++ statement, add this :
if($i % 4 == 0)
{
echo "</div>";
}
<?php
$wrap_count = 2; // you can change this no of divs to wrap
foreach ($categories as $category) :
$i+=1;
if($i%$wrap_count==1):
echo '<div class="row">';
endif;?>
<div class="col-lg-3 col-md-3">.....</div>
if($i%$wrap_count==0) : echo '</div>'; endif; endforeach;
?>
Works Fine For me
Try this one. It works for me.
<?php $count = 1; ?>
<?php foreach ($model->userProfile->portfolio as $item): ?>
<?php if ($count % 4 == 1): ?>
<div class="row" style="margin-bottom: 30px;">
<?php endif ?>
<div class="col-md-3">
</div>
<?php if ($count % 4 == 0): ?>
</div>
<?php endif ?>
<?php $count++ ?>
<?php endforeach ?>
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.
This is my foreach list:
foreach ($items as $key => $item):
if (++$i == 21) break;
$output.='<div class="row-fluid"><div class="span12 block">
<div class="pull-left">
'.$item->title.'
</div>
<div class="pull-right">
<p class="muted">'.date("m/d/Y", $item->date).'</p>
</div>
<div class="clearfix"></div>
</div></div>';
endforeach;
echo $output;
The result is a well orderd list of 21 items picked from an xml feed. What i'm trying to do is to add a custom row between (for example) line 10 and 11.
Can anyone suggest me a good way?
You can do that by adding a simple if statement. If you want every 10th line to have that you can use mod operator %.
foreach ($items as $key => $item):
if (++$i == 21) break;
if ($i == 9) {
$output .= '<div>NEW LINE </div>';
}
$output.='<div class="row-fluid"><div class="span12 block">
<div class="pull-left">
'.$item->title.'
</div>
<div class="pull-right">
<p class="muted">'.date("m/d/Y", $item->date).'</p>
</div>
<div class="clearfix"></div>
</div></div>';
endforeach;
echo $output;
You can use flag variables.
Before loop set initial value of a variable $rowcount=1
and between loop you can increment this variable from +1.
and check
<code>
if($rowcount=10)
{
//do something
}
</code>
Use this solution