PHP loop split by 4 - php

How would I achieve this PHP task?
I have an unordered html list and and array.
My code adds list tags to each item in the array to create one big unordered list
<ul>
<?php foreach ($rows as $id => $row): ?>
<li><?php print $row ?></li>
<?php endforeach; ?>
</ul>
current output below
<ul>
<li>01</li>
<li>02</li>
<li>.....</li>
<li>.....</li>
<li>15</li>
</ul>
What I want is to split the list items so that they are in groups of 4 as sub unordered lists. If the number is not divisible by 4 then the remainder should be a smaller list at the end, for example.
<ul>
<ul>
<li>01</li>
<li>02</li>
<li>.....</li>
<li>.....</li>
</ul>
<ul>
<li>05</li>
<li>06</li>
<li>.....</li>
<li>.....</li>
</ul>
<ul>
<li>09</li>
<li>10</li>
</ul>
</ul>
Thanks in advance.

<ul>
<?php foreach ($rows as $id => $row): ?>
<?php if ($id > 0 && $id % 4 === 0): ?>
</ul><ul>
<?php endif ;?>
<li><?php echo $row; ?></li>
<?php endforeach; ?>
</ul>
(Note that if the key of your $rows array is not simply an index number, you'll need to maintain your own counter variable.)

<?php
$id=0;
foreach ($rows as $id => $row)
{
$id+=1;
if ($id % 4 == 0)
{
echo "<ul>";
}
echo "<li>$i</li>";
if ($id % 4 == 0)
{
echo "</ul>";
}
}
if ($id % 4 != 0)
{
echo "</ul>";
}
?>

foreach ($rows as $id => $row) {
if ($id % 4 == 0) {
// do something
}
}

Try something like this :
<?php
$rows = array("2","3","5","6","8","9","0","3","5");
$i =0;
foreach ($rows as $id => $row):
if($i % 4 == 0)
{ echo "</ul><ul>";}
$i++;
?>
<li><?php print $row ?></li>
<?php endforeach; ?>
</ul>

In the end this is the solution I went for. This solution includes a statement to close the tags if there are a number of items not divisible by four, for example if there are five items in total. Thanks to everyone, I couldn't have done it without your input.
$count;
foreach ($rows as $id => $row)
{
if ($count % 4 == 0)
{
echo "<ul>";
}
echo '<li>' . $row . '</li>';
if ($count % 4 == 3 || $count == count($rows)-1)
{
echo "</ul>";
}
$count++;
}

Related

Create a menu from database (mixed sub menus)

I created a database to store a menu informations with 3 level (2 sub menus level).
You can see it on the left here : https://volt-services.fr/sites/stge/index.php#
Here is the table in the database:
And the code to translate it to HTML:
<?php
$req = $DB->query("SELECT * FROM menu ORDER BY ordered");
foreach ($req as $r) {
if($r->level == 1) {
$tab[$r->ordered] = array($r->id,$r->name,$r->class,$r->icon);
} elseif ($r->level == 2) {
$tab[$r->parent][4][$r->ordered] = array($r->id,$r->name);
} elseif ($r->level == 3) {
$tab[$r->cat][4][$r->parent][2][$r->ordered] = array($r->id,$r->name);
}
}
foreach ($tab as $key => $value) {
?>
<li data-menu="<?= $value[0]; ?>" class="<?= $value[2]; ?> menu-item">
<span class="material-icons-outlined"><?= $value[3]; ?></span>
<span class="titre_menu"> <?= $value[1]; ?></span>
<ul id="sub_menu<?= $value[0]; ?>" class="box_sub_exp <?= $value[2]; ?>">
<?php foreach ($value[4] as $ke => $val) { // SUB MENU POSITION 4 ?>
<li class="<?= $value[2]; ?> submenu-item"><?= $val[1]; ?>
<?php if(!empty($val[2])) { // IS A MENU IN POSITION 2 ?>
<ul class="box_sub_sub_exp">
<?php foreach ($val[2] as $k => $v) { // SUB MENU POSITION 2 ?>
<li class="<?= $value[2]; ?> submenu-item"><?= $v[1]; ?></li>
<?php } ?>
</ul>
<?php } ?>
</li>
<?php } ?>
</ul>
</li>
<?php } ?>
</ul>
</nav>
</section>
On the first sub menu everything is OK. But on the second, the first line is missing, on the third 2 first lines are missing, etc...
I think there is a problem with my loop, could you please help me to find it ?
FIXED : the problem was in the request, not "ORDER BY ordered" but by "id"
Even if you set a numeric key with $r->ordered, you have to sort your table before your display loop !
Give a numeric key to a table line doesn't "auto-sort" it on loop.
Try using ksort() on $tab before your display foreach. So it's will use keys you've define and sort your table in order.

Is it possible to close </ul> and add new <ul> in the loop?

I am display data from the database. Currently, I have 6 records in my database and I am getting my output like
<ul>
<li>Records1</li>
<li>Records2</li>
<li>Records3</li>
<li>Records4</li>
<li>Records5</li>
<li>Records6</li>
</ul>
Now what I am doing is, I have to close the </ul> tag after 4th li tag and then start new ul after 4th li.
My expected output is
<ul>
<li>Records1</li>
<li>Records2</li>
<li>Records3</li>
<li>Records4</li>
</ul>
<ul>
<li>Records5</li>
<li>Records6</li>
</ul>
is it possible?
I am using below code
<?php
if ($tyler_query->have_posts()) {
$index = 0;
$check=0;
$first4=0;
while ( $tyler_query->have_posts() ) {
$tyler_query->the_post();
if ($index < 4) {
if ($first4==0){?>
<ul>
<?php $first4=1;}?>
<li>
<!--output here-->
</li>
<?php if ($first4==4){?>
</ul>
<?php }?>
<?php }
else {
if ($check==0){?>
<ul>
<?php $check=1;}?>
<li>
<!--output here-->
</li>
<?php } $index++;}?>
</ul>
<?php }?>
You can just insert a closing tag followed by an opening tag, whenever it meets your condition. In the following after every third item:
<?php
$items = [
'Syd',
'Roger',
'Nick',
'David',
'Richard'
];
$i = 0;
echo '<ul>';
foreach($items as $item) {
if($i++%3 == 0)
echo '</ul><ul>';
echo '<li>' . $item . '</li>';
}
echo '</ul>';
Output:
<ul><li>Syd</li><li>Roger</li><li>Nick</li></ul><ul><li>David</li><li>Richard</li></ul>
It's quick example. Hope help you.
if ($tyler_query->have_posts()) {
$index = 0;
$check = 6;
?>
<ul>
<?php while ($tyler_query->have_posts()) {
$tyler_query->the_post(); ?>
<li><?php echo 'some_value' ?></li>
<?php if ($index % $check === 0 ) { ?>
</ul><ul>
<?php }
$index++;
} ?>
</ul>
<?php } ?>
your code would work if you echo the HTML tag/output you want to see in the browser.
<?php
if ($tyler_query->have_posts()) {
$index = 0;
$check = 0;
$first4 = 0;
while ($tyler_query->have_posts()) {
$tyler_query->the_post();
$output = "whatever the output object is";
if ($index < 4) {
if ($first4 == 0) {
echo '<ul>';
$first4 = 1; // increment so that the this if block wont trigger again
}
echo '<li>' . $output . '</li>';
// increment so that the next if block trigger once
if ($first4 == 4) {
echo '</ul>';
}
$first4++;
}
if ($index >= 4){
if ($check == 0) {
echo '<ul>';
$check = 1;
}
// assuming you want to have the rest of the data in this block.
// data 5 and above
else {
echo '<li>' . $output . '</li>';
}
}
$index++;
}
echo '</ul>';
}
?>

Limit the number of categories shows on page

I have this portion of code where categories are loaded from txt file.
<?php
foreach ($categories as $cat) {
if ($cat['word'] == false)
continue;
?>
<li>
<?php echo $cat['name']?>
</li>
<?php } ?>
The problem is that they are a lot because they are pulled from outside and populated dynamically in the file. Because of that I want to limit them to 15 but I'm unable to do it.
I've tried with for and while, like:
<?php
foreach ($categories as $cat) {
if ($cat['word'] == false)
continue;
for($cat['word'] = 0; $cat['word'] <=15; $cat['word']++){
?>
<li>
<?php echo $cat['name']?>
</li>
<?php }
}?>
And
<?php
foreach ($categories as $cat) {
if ($cat['word'] == false)
continue;
while($cat['word'] = 15;){
?>
<li>
<?php echo $cat['name']?>
</li>
<?php }
}?>
Both variants result in empty names.
Will the following work for you?
<?php $count = 0; ?>
<?php foreach ($categories as $cat) :?>
<?php if ($cat['word'] == false) continue; ?>
<li>
<?php echo $cat['name']?>
</li>
<?php if ($count >= 15) break; ?>
<?php $count++; ?>
<?php endforeach; ?>
Assuming you'd like to filter out the $cat['word'] == false entries before limiting the results to the first 15 (ie so you get up to 15 entries shown), try something like this...
$filtered = array_filter($categories, function($cat) {
return $cat['word']; // only include truthy "word" entries
});
foreach (array_slice($filtered, 0, 15) as $cat) : ?>
<li>
<?= $cat['name'] ?>
</li>
<?php endforeach ?>
<?php
$counter = 0;
foreach ($categories as $cat) {
if ($cat['word'] == false){
continue;
}
if($counter < 15) {
echo '<li>
<?php echo $cat['name']?>
</li>'
$counter++;
}} ?>
Can be refactored.

Making a nested list with php foreach

I'm trying to make a nested list with php by using a foreach loop but I'm kind of stuck now. My code uses a foreach loop and checks if the item is a heading, if it is it will start a nested list below it. The problem now is that if it's not a heading I want to put the corresponding list items into a single ul element below its heading. Now as you can see it puts every single list items that isn't a heading into a seperate ul element of its own because of the foreach loop. How can I fix this?
<ul>
<?php foreach($listitems as $listitem) : ?>
<?php if( $listitem['heading'] == 1) : ?>
<li><?php echo $listitem['listitem']; ?><!--begin nested list-->
<?php endif; ?>
<?php if( $listitem['heading'] == 0) : ?>
<ul><li><?php echo $listitem['listitem']; ?></li></ul>
<?php endif; ?>
<?php endforeach; ?>
</li><!--end nested list-->
</ul>
This is the desired html output:
<ul>
<li>Javascript Basics<!--begin nested list-->
<ul>
<li>Getting Started</li>
<li>Data and Variables</li>
<li>Functions</li>
<li>Scope</li>
<li>Working With Objects</li>
<li>Creating Objects</li>
<li>Arrays</li>
<li>Conditions And Decisions</li>
<li>Loops</li>
</ul>
</li><!--end nested list-->
</ul>
You need to set the inner lists start and end tags when the heading changes.
Something like this
<ul>
<?php
$NonHeadCount = 0;
$HeadingOpen = false;
foreach($listitems as $listitem)
{
if( $listitem['heading'] == 1)
{
$HeadingOpen = true;
if ($NonHeadCount != 0)
{
echo "</ul>";
}
echo "<li>".$listitem['listitem'];
$NonHeadCount = 0;
}
if( $listitem['heading'] == 0)
{
if ($NonHeadCount == 0)
{
echo "<ul>";
}
echo "<li>".$listitem['listitem']."</li>";
}
}
if ($NonHeadCount != 0)
{
echo "</ul>";
}
if ($HeadingOpen)
{
echo "</li>";
}
?>
</ul>
You have to change the $listitems format.
Some like this:
<?php
$listitems = array(
'item1' => array(
'item11',
'item12',
'item13'
),
'item2' => array(
'item21',
'item22',
),
'item3',
'item4'
);
?>
Then, do this:
<?php
echo "<ul>";
foreach($listitems as $item => $listitem):
echo "<li>$item</li>";
if(count($listitem) > 0):
echo "<ul>";
foreach($lisitem as $item):
echo "<li>$item</li>";
endforeach;
echo "</ul>";
endif;
endforeach;
echo "<ul>";
?>

how to add big space

<?php foreach ($rows as $id => $row): ?>
<li class="<?php print $classes[$id]; ?>"><?php print $row; ?></li>
<?php endforeach; ?>
the above code is used to output an article list. now i want to add big space after the lines which is the multiple of 10.namely,add a big space (eg:margin-bottom:30px,only to after every 10 bullet points but the space between other li is 15px )after every 10 bullet points. how to change the above code. then i can use css to get that.
–
Although I don't have a clue what you mean by 'big space', I assume you want to place an arbitry HTML tag after every 10th list item. You can do this like so, for example:
<?php $i = 0; ?>
<?php foreach ($rows as $id => $row): ?>
<li class="<?php print $classes[$id]; ?>"><?php print $row; ?></li>
<?php if ($i++ === 10): ?><br /><?php $i = 0; endif; ?>
<?php endforeach; ?>
EDIT, you clarified:
no,eg:30px, but the space between other <li> is 20px.
Which can be done like so:
<?php $i = 1; ?>
<?php foreach ($rows as $id => $row): ?>
<?php $i++; ?>
<li style="margin-bottom:<?php echo ($i === 10) ? : '30' : '20'); ?>px;" class="<?php print $classes[$id]; ?>"><?php print $row; ?></li>
<?php if ($i === 10) $i = 1; ?>
<?php endforeach; ?>
The modulus operator (%) is ideal for this:
<?php $i = 0; foreach ( $rows as $id => $row ): ?>
<li style="margin-bottom: <?php echo $i ++ % 10 ? '30' : '20' ?>px;" class="<?php echo $classes[$id] ?>">
<?php echo $row ?>
</li>
<?php endforeach ?>
As a slight amendment to Aron's code, if you wanted to use CSS to style the <li>:
<?php $i = 1;
foreach ($rows as $id => $row):
if($i === 10){
$end_class = ' end-class';
$i = 1;
} else {
$end_class = '';
$i++;
}
echo '<li class="' . $classes[$id] . $end_class . '">' . $row . '</li>';
endforeach;
?>
You can then apply the style to .end-class.

Categories