How to build multi level navigation with PHP - php

Im working on a prototype, and would like to build a multi level navigation - however not by looping through an array. I have a $depth and a $children, which should determine the depth of the navigation and the number of children on each level. So $depth = 4, $children = 8 would yield 4096 menu items.
This is a snippet af the output I would like:
<ul>
<li class="level-1">
Subject 1
<ul>
<li class="level-2">
Subject 1.1
<ul>
<li class="level-3">
Subject 1.1.1
</li>
...
</ul>
</li>
...
</ul>
</li>
...
</ul>
So far I have tried this, but I cant get my head around it :(
function draw_list ($depth, $children) {
echo '<ul>';
for ($i = 0; $i < $children; $i++) {
echo '<li>' . ($i++);
$depth--;
if ($depth > 0) {
echo draw_list($depth, $children);
}
echo '</li>';
}
echo '</ul>';
}

Several things required as I see it...
The $depth--; needs to be outside of the for loop
You were incrementing $i twice, once in the for statement, and then again on the echo '<li>' . ($i++);
The $depth check was stopping one early, so make >= instead of just > (Edit, thinking about it, this is an incorrect statement)
That should give you...
function draw_list ($depth, $children) {
echo '<ul>';
$depth--;
for ($i = 0; $i < $children; $i++) {
echo '<li>' . $i;
if ($depth > 0) {
echo draw_list($depth, $children);
}
echo '</li>';
}
echo '</ul>';
}
Update
For the display of the level numbering, try passing a string value through as a parameter...
function draw_list ($depth, $children, $display=''){
echo '<ul>';
$depth--;
for ($i = 0; $i < $children; $i++) {
echo '<li>' . $display . ($i + 1);
if ($depth > 0) {
echo draw_list($depth, $children, $display . ($i + 1) . '.');
}
echo '</li>';
}
echo '</ul>';
}

I ended up doing this:
function build_nav ($depth, $children, $levels = array()) {
echo '<ul>';
$depth--;
for ($i = 0; $i < $children; $i++) {
$levels[$depth] = $i+1;
echo '<li>';
echo 'Subject: ' . implode('.', $levels);
if ($depth > 0) {
build_nav($depth, $children, $levels);
}
echo '</li>';
}
echo '</ul>';
}

Related

PHP - How to wrap every 2 items of a 'for' loop within a div

I'm looking for a way to wrap every too items of this very basic for loop within a div :
<?php
for( $i=1; $i<=50; $i++ )
{
echo "<div><a href='item-".$i."'>".$i."</a></div>";
}
?>
This produces the following :
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
The output i need would be :
<div>1 2</div>
<div>3 4</div>
Thanks
Easiest way i can think of is by doing this. This also works if you have a resultset from a database, or an array of item objects, just replace the range() function with the array.
<?php
foreach (array_chunk(range(1, 50), 2) as $chunk) {
echo "<div>";
foreach ($chunk as $itemId) {
echo "<a href='item-" . $itemId . "'>" . $itemId . "</a>";
}
echo "</div>" . PHP_EOL;
}
Use modulo operator
code:
<?php
$chunks = 2;
$display = true;
for( $i=1; $i<=6; $i++ )
{
if ($display && ($i % $chunks || $chunks === 1)) {
echo "<div>";
$display = false;
$last = true;
}
echo "<a href='item-".$i."'>".$i."</a>";
if (!($i % $chunks)) {
echo "</div>" . PHP_EOL;
$display = true;
$last = false;
}
}
if ($last) {
echo "</div>" . PHP_EOL;
}
generates:
<div><a href='item-1'>1</a><a href='item-2'>2</a></div>
<div><a href='item-3'>3</a><a href='item-4'>4</a></div>
<div><a href='item-5'>5</a><a href='item-6'>6</a></div>
and with:
$chunks = 3;
you will get:
<div><a href='item-1'>1</a><div><a href='item-2'>2</a><a href='item-3'>3</a></div>
<div><a href='item-4'>4</a><div><a href='item-5'>5</a><a href='item-6'>6</a></div>
and so one.

How do I count elements in a while loop and apply css class?

I have a repeater from ACF and what I want to is loop and count the items and based on the counted items output a particular css class.
Can I get help so the output of css classes depends on the counted items. For example if there was six items the class would be col-6 etc...
<?php
if( have_rows('rainbow') ):
$counter = 0;
while( have_rows('rainbow') ): the_row();
// vars
$name = get_sub_field('name');
$age = get_sub_field('age');
$cssClass = 'col';
for($i = 0; $i < $counter; $i++) {
if($counter === 6) {
$cssClass = 'col-lg-4';
} elseif ($counter == 4) {
$cssClass = 'col-xl-6';
}
else {
$cssClass = 'col';
}
}
echo '<div class=\'' . $cssClass. '\'>';
echo "<h4>" . $name . "</h4>";
echo "<p>" . $age . "</p>";
echo $counter;
echo '</div>';
$counter++;
endwhile;
endif;
?>
Don't know why are you using for loop here, $i < $counter this condition cant be true because $i and $counter both of them started from 0. so 0 < 0 == FALSE
You just need to remove for loop inside your while loop.
Or, if you are using for loop somewhere else in your code, then you can just move your conditions outside the for loop.
Second Solution:
Second, if you start $counter from 1 then you can achieve your desired result as given example:
<?php
$array = array(1,2,3,4,5,6);
$counter = 1;
foreach ($array as $key => $value) {
$cssClass = 'col';
for($i = 0; $i < $counter; $i++) {
if($counter === 6) {
$cssClass = 'col-lg-4';
} elseif ($counter == 4) {
$cssClass = 'col-xl-6';
}
else {
$cssClass = 'col';
}
}
echo $cssClass."<br/>";
$counter++;
}
?>
Result:
col
col
col
col-xl-6
col
col-lg-4
<?php
$counter = 1;
while( have_rows('rainbow') ): the_row();
// vars
$name = get_sub_field('name');
$age = get_sub_field('age');
if ( $counter == 4 ) {
$cssClass = 'col-xl-6';
} elseif ( $counter == 6 ) {
$cssClass = 'col-lg-4';
} else {
$cssClass = 'col';
}
echo '<div class="' . $cssClass . '">';
echo "<h4>" . $name . "</h4>";
echo "<p>" . $age . "</p>";
echo $counter;
echo '</div>';
$counter++;
endwhile;
try this

How to create ordinal numbers for list item?

I have a list item with this code:
foreach ($medias as $i => $media) {
$html .= "<li class=''>...</li>";
}
I want output as below:
<li class="id-1">...</li>
<li class="id-2">...</li>
<li class="id-3">...</li>
<li class="id-4">...</li>
....
Thank for your help!
Try this:
for($i=0; $i<count($media); $i++) {
$html .= '<li class="id-'.($i+1).'">...</li>';
}
Try this:
foreach ($medias as $i => $media) {
$html .= "<li class='".($i + 1)."'>...</li>";
}
Try this:
$x=0;
foreach ($medias as $i => $media) {
$x++;
echo "<li class='id-".$x."'>...</li>";
}

How to show the value of two related arrays in php?

I have two arrays myarray1 has name of images and myarray2 has the address of images,
I am going to show image names and their addresses in pagination but do not know how to complete the code.
$pages = array_chunk($myarray1,10);
$addrs = array_chunk($myarray2,10);
$page_number = 1
$count = 0;
echo'<table>';
echo'<tr>';
foreach ($pages[$page_number] as $i) {
$counter++;
if ($count == 5) {
echo '</tr><tr>';
$counter = 0;
}
echo'<td>'.$i. " AND " . <<Value of addrs array goes here
echo'</td>';
}
.......
I'll do it on this way
$count = 1;
foreach ($pages[$page_number] as $key => $i) {
if ($count % 5 == 0) {
echo '</tr><tr>';
echo '</div>';
echo '</div>';
}
echo'<td>'.$i. " AND " . $addrs[$page_number][$key]
echo'</td>';
$count++; // increase at the end.
}
if you can try to var_dump those arrays before foreach just to be clear how structure looks like.
Try something like this: (note also the counter++ is changed in $count++)
foreach ($pages[$page_number] as $key => $i) {
$count++;
if ($count == 5) {
echo '</tr><tr>';
echo '</div>';
echo '</div>';
$count = 0;
}
echo'<td>'.$i. " AND " . $addrs[$page_number][$key]
echo'</td>';
}

how to write the condition?

$tree = taxonomy_get_tree($vid);
print "<li>"; // 1 line
foreach ($tree as $term ) { // 2 lines
$diffdepth=0;
if ($term->depth > $depth) {
print "<ul class='haschild'><li>";
$depth = $term->depth;
}
the above is the original code, now I want according to $term->depth > $depth make a condition to output.( print "<li>"; ) this line.
namely,
if ($term->depth > $depth) {
echo '<li class="parent">';
}
else {
print "<li>";
}
but $term->depth can use after foreach loop, but i want to use it at 1 line, how do i do?
Instead of printing in-line, assign your desired output to variables and then send it to the browser after the logic is complete.
$tree = taxonomy_get_tree($vid);
$parent = ""; // 1 line
$child = "";
foreach ($tree as $term) { // 2 line
$diffdepth=0;
if ($term->depth > $depth) {
$parent = "<li class='parent'>";
$child .= "<ul class='haschild'><li>";
$depth = $term->depth;
} else {
$parent = "<li>";
}
}
echo $parent . $child;
Please note you'll need to finish this up by adding all the applicable </li>s and whatnot, but this should get you started.
Use a counter:
$tree = taxonomy_get_tree($vid);
$counter = 0;
foreach ($tree as $term)
{
...
if ($term->depth > $depth)
{
if ($counter == 0) { echo '<li class="parent">'; }
else { echo '<li>'; }
print "<ul class='haschild'><li>";
$depth = $term->depth;
}
...
$counter++;
}
If you need to write more differences based on your condition, you can turn tha above into:
$tree = taxonomy_get_tree($vid);
$counter = 0;
foreach ($tree as $term)
{
...
if ($term->depth > $depth)
{
if ($counter == 0) { echo '<li class="parent">'; }
print "<ul class='haschild'><li>";
$depth = $term->depth;
}
else
{
if ($counter == 0) { echo '<li>'; }
...
}
...
$counter++;
}
if you want to build something like parent child hierarchy then you should check it by click here

Categories