ORIGINAL POST
I want to create a navigation menu in PHP with Bootstrap 4. Problem is that one of the <li>
's is not right (the one from dropdown
, it doesn't become a dropdown but just a normal nav-item
). This code works alright if you want to make a normal menu with <ul>
and <li>
but with bootstrap you need to have a nav-item dropdown
on the <li>
of id 2
named Dropdown
. How would I do this?
I hope this is enough information.
This is the array():
array (size=3)
0 =>
array (size=5)
0 =>
array (size=3)
'id' => string '1' (length=1)
'menu_naam' => string 'Home' (length=4)
'parent_id' => string '0' (length=1)
1 =>
array (size=3)
'id' => string '2' (length=1)
'menu_naam' => string 'Dropdown' (length=4)
'parent_id' => string '0' (length=1)
2 =>
array (size=3)
'id' => string '3' (length=1)
'menu_naam' => string 'Winkelwagen' (length=11)
'parent_id' => string '0' (length=1)
3 =>
array (size=3)
'id' => string '4' (length=1)
'menu_naam' => string 'Contact' (length=7)
'parent_id' => string '0' (length=1)
4 =>
array (size=3)
'id' => string '5' (length=1)
'menu_naam' => string 'Feedback' (length=8)
'parent_id' => string '0' (length=1)
2 =>
array (size=1)
0 =>
array (size=3)
'id' => string '6' (length=1)
'menu_naam' => string 'Sub Menu' (length=8)
'parent_id' => string '2' (length=1)
6 =>
array (size=1)
0 =>
array (size=3)
'id' => string '7' (length=1)
'menu_naam' => string 'Sub Sub Menu' (length=12)
'parent_id' => string '6' (length=1)
This is the PHP I use to build the menu:
<?php
function menu_builder() {
global $pdo;
$sql = $pdo->prepare("SELECT * FROM menus");
if ($sql->execute()) {
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$array[$row['parent_id']][] = $row;
}
loop_array($array);
}
}
function loop_array($array = array(), $parent_id = 0) {
if (!empty($array[$parent_id])) {
echo "<ul class=\"navbar-nav mr-auto\">";
foreach ($array[$parent_id] as $item) {
echo "<li class=\"nav-item\">";
echo "<a href=\"#\" class=\"nav-link\">" . $item['menu_naam'] . "</a>";
loop_array2($array, $item['id']);
echo "</li>";
}
echo "</ul>";
}
}
function loop_array2($array = array(), $parent_id = 0) {
if (!empty($array[$parent_id])) {
echo "<li class=\"nav-item dropdown\">";
foreach ($array[$parent_id] as $item) {
echo "<a href=\"#\" class=\"nav-link dropdown-toggle\" id=\"navbarDropdown\" role=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">" . $item['menu_naam'] . "</a>";
loop_array3($array, $item['id']);
}
echo "</li>";
}
}
function loop_array3($array = array(), $parent_id = 0) {
if (!empty($array[$parent_id])) {
echo "<div class=\"dropdown-menu\" aria-labelledby=\"navbarDropdown\">";
foreach ($array[$parent_id] as $item) {
echo "<a class=\"dropdown-item\" href=\"#\">" . $item['menu_naam'] . "</a>";
}
echo "</div>";
}
}
I really hope someone can help me with this, should I add something to the database so it will know it's a dropdown? I think my code is too big and to complicated, there should be a easyer way but I don't know how. I think I need a whole other approach. If you could only help me in the right direction it would be fine too.
Also some credit to the guy who made the sub menu tutorial (here you can also see how the menu is build with <ul>
and <li>
and does exactly what it needs to do, but not for bootstrap
): https://www.youtube.com/watch?v=Ol63V4R-TdI
EDIT: I found a kind of a solution over here: Dynamic menu php bootstrap mysql
What I have now is:
function drawMenu($pdo, $parent_id, $level = null) {
$sql = $pdo->prepare("SELECT * FROM menus where parent_id = $parent_id");
$sql->execute();
foreach ($sql->fetchAll() as $row) {
$sql = $pdo->prepare("SELECT count(*) FROM menus where parent_id = " . $row['id'] . "");
$sql->execute();
// The item is parent, so do recursion again
//var_dump($sql->fetchAll()[0][0]);
if($sql->fetchAll()[0][0] !== '0' && $level !== 0){
echo "<li class=\"nav-item dropdown\"><a href=\"" . $row['url'] . "\" class=\"nav-link dropdown-toggle\" id=\"navbarDropdownMenuLink\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">" . $row['menu_naam'] . "</a><div class=\"dropdown-menu\" aria-labelledby=\"navbarDropdownMenuLink\">\n";
drawMenu($pdo, $row[0], $level - 1);
echo "</div></li>\n";
}
else { // The item is a leaf or we reach the end level, i.e. base case, so do print the item label
echo "<li class=\"nav-item\"><a href=\"#\" class=\"nav-link\">" . $row['menu_naam'] . "</a></li>\n";
}
}
}
?>
<header class="navbar navbar-dark bg-dark fixed-top navbar-expand-sm">
<a class="navbar-brand" href="#">Webshop</a>
<button class="navbar-toggler" style="background: #000000" type="button" data-toggle="collapse" data-target="#navbar-header" aria-controls="navbar-header">
☰
</button>
<div class="navbar-collapse collapse show" id="navbar-header">
<ul class="navbar-nav mr-auto">
<?php
drawMenu($pdo, 0, null);
?>
</ul>
</div>
</header>
But the problem now is that it prints multiple
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
The HTML looks like this now:
<div class="navbar-collapse collapse show" id="navbar-header">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a href="#" class="nav-link"><span class="fas fa-home"></span> Home</a></li>
<li class="nav-item dropdown"><a href="#" class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a><div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<li class="nav-item dropdown"><a href="#" class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Sub Menu</a><div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<li class="nav-item"><a href="#" class="nav-link">Sub-sub Menu</a></li>
</div></li>
</div></li>
<li class="nav-item"><a href="#" class="nav-link"><span class="fas fa-shopping-cart"> </span> Winkelwagen</a></li>
<li class="nav-item"><a href="#" class="nav-link">Contact</a></li>
<li class="nav-item"><a href="#" class="nav-link">Feedback</a></li>
</ul>
</div>