原始帖子
我想在PHP中使用Bootstrap 4创建一个导航菜单。问题是其中一个<li>
不正确(来自dropdown
的那个,它没有&#39;成为一个下拉列表,但只是一个正常的nav-item
)。如果您想使用<ul>
和<li>
创建普通菜单,但是如果您需要在nav-item dropdown
身份<li>
上设置2
,则此代码可以正常运行命名为Dropdown
。我该怎么做?
我希望这是足够的信息。
这是数组():
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)
这是我用来构建菜单的PHP:
<?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>";
}
}
我真的希望有人可以帮我解决这个问题,我应该向数据库添加一些东西,以便它知道它是一个下拉列表吗?我认为我的代码太大而且复杂,应该有一个更简单的方法,但我不知道如何。我想我需要一个完整的方法。如果你只能帮助我朝着正确的方向前进,那也没关系。
对于制作子菜单教程的人来说也有一些功劳(在这里你也可以看到如何使用<ul>
和<li>
构建菜单并完成它需要做的事情,但不是bootstrap
):https://www.youtube.com/watch?v=Ol63V4R-TdI
修改 我在这里找到了一种解决方案:Dynamic menu php bootstrap mysql
我现在拥有的是:
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>
但现在的问题是它会打印多个
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
HTML现在看起来像这样:
<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>
答案 0 :(得分:0)
我将menu
添加到数据库并检查它是否为0或1.我已经删除了子子菜单,但如果我添加它,我会更新这篇文章。
function menu_builder($pdo, $parent_id) {
$sql = $pdo->prepare("SELECT * FROM menus");
if ($sql->execute()) {
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$array[$row['parent_id']][] = $row;
}
main_menu($array);
}
}
function main_menu ($array, $parent_id = 0) {
if (!empty($array[$parent_id])) {
foreach ($array[$parent_id] as $item) {
if ($item['menu'] == '0') {
echo " <li class=\"nav-item\">" . PHP_EOL;
echo " <a class=\"nav-link\" href=\"#\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
main_menu($array, $item['id']);
echo " </li>" . PHP_EOL;
}
elseif ($item['menu'] == '1') {
echo " <li class=\"nav-item dropdown\"><a class=\"nav-link dropdown-toggle\" href=\"#\" id=\"navbarDropdown\" role=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
sub_menu($array, $item['id']);
echo " </li>" . PHP_EOL;
}
}
//echo "</div>" . PHP_EOL;
echo "</li>" . PHP_EOL;
}
}
function sub_menu ($array, $parent_id) {
if (!empty($array[$parent_id])) {
echo " <div class=\"dropdown-menu\" aria-labelledby=\"navbarDropdown\">" . PHP_EOL;
foreach ($array[$parent_id] as $item) {
echo " <a class=\"dropdown-item\" href=\"" . $item['url'] . "\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
}
echo " </div>" . PHP_EOL;
}
}
?>
<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">
<?php
echo "<ul class=\"navbar-nav mr-auto\">";
echo menu_builder($pdo, 0);
echo "</ul>" . PHP_EOL;
?>
</div>
</header>
编辑:要获得子菜单,代码如下所示,您还需要以下css
。
function menu_builder($pdo, $parent_id) {
$sql = $pdo->prepare("SELECT * FROM menus");
if ($sql->execute()) {
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$array[$row['parent_id']][] = $row;
}
main_menu($array);
}
}
function main_menu ($array, $parent_id = 0) {
if (!empty($array[$parent_id])) {
foreach ($array[$parent_id] as $item) {
if ($item['menu'] == '0') {
echo " <li class=\"nav-item\">" . PHP_EOL;
echo " <a class=\"nav-link\" href=\"" . $item['url'] . "\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
main_menu($array, $item['id']);
echo " </li>" . PHP_EOL;
}
elseif ($item['menu'] == '1') {
echo " <li class=\"nav-item dropdown\">". PHP_EOL;
echo " <a class=\"nav-link dropdown-toggle\" href=\"" . $item['url'] . "\" id=\"navbarDropdown\" role=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
sub_menu($array, $item['id']);
echo " </li>" . PHP_EOL;
}
}
}
}
function sub_menu ($array, $parent_id) {
if (!empty($array[$parent_id])) {
echo " <div class=\"dropdown-menu\" aria-labelledby=\"navbarDropdown\">" . PHP_EOL;
foreach ($array[$parent_id] as $item) {
if ($item['sub_menu'] == '0') {
echo " <a class=\"dropdown-item\" href=\"" . $item['url'] . "\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
}
elseif ($item['sub_menu'] == '1') {
echo " <div class=\"dropdown-submenu\">" . PHP_EOL;
echo " <a class=\"dropdown-item dropdown-toggle\" href=\"" . $item['url'] . "\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
sub_sub_menu($array, $item['id']);
echo " </div>" . PHP_EOL;
}
}
echo " </div>" . PHP_EOL;
}
}
function sub_sub_menu ($array, $parent_id) {
if (!empty($array[$parent_id])) {
echo " <div class=\"dropdown-menu\" aria-labelledby=\"navbarDropdown\">" . PHP_EOL;
foreach ($array[$parent_id] as $item) {
echo " <a class=\"dropdown-item\" href=\"" . $item['url'] . "\">" . $item['menu_naam'] . "</a>" . PHP_EOL;
}
}
echo " </div>" . PHP_EOL;
}
子菜单需要的CSS,因为默认情况下bootstrap不支持它(https://stackoverflow.com/a/45755948/2877035):
.dropdown-submenu {
position: relative;
}
.dropdown-submenu a::after {
transform: rotate(-90deg);
position: absolute;
right: 6px;
top: .8em;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-left: .1rem;
margin-right: .1rem;
}
和jQuery:
$('.dropdown-menu a.dropdown-toggle').on('click', function(e) {
if (!$(this).next().hasClass('show')) {
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
}
var $subMenu = $(this).next(".dropdown-menu");
$subMenu.toggleClass('show');
$(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function(e) {
$('.dropdown-submenu .show').removeClass("show");
});
return false;
});
答案 1 :(得分:0)
我对bootstrap 4.1做了一些更改
<style type="text/css">
.navbar .dropdown-toggle, .navbar .dropdown-menu a {
cursor: pointer;
}
.navbar .dropdown-item.active, .navbar .dropdown-item:active {
color: inherit;
text-decoration: none;
background-color: inherit;
}
.navbar .dropdown-item:focus, .navbar .dropdown-item:hover {
color: #16181b;
text-decoration: none;
background-color: #f8f9fa;
}
@media (min-width: 767px) {
.navbar .dropdown-toggle:not(.nav-link)::after {
display: inline-block;
width: 0;
height: 0;
margin-left: .5em;
vertical-align: 0;
border-bottom: .3em solid transparent;
border-top: .3em solid transparent;
border-left: .3em solid;
}
}
</style>
<script type="text/javascript">
$(document).ready(function () {
$('.navbar .dropdown-item').on('click', function (e) {
var $el = $(this).children('.dropdown-toggle');
var $parent = $el.offsetParent(".dropdown-menu");
$(this).parent("li").toggleClass('open');
if (!$parent.parent().hasClass('navbar-nav')) {
if ($parent.hasClass('show')) {
$parent.removeClass('show');
$el.next().removeClass('show');
$el.next().css({"top": -999, "left": -999});
} else {
$parent.parent().find('.show').removeClass('show');
$parent.addClass('show');
$el.next().addClass('show');
$el.next().css({"top": $el[0].offsetTop, "left": $parent.outerWidth() - 4});
}
e.preventDefault();
e.stopPropagation();
}
});
$('.navbar .dropdown').on('hidden.bs.dropdown', function () {
$(this).find('li.dropdown').removeClass('show open');
$(this).find('ul.dropdown-menu').removeClass('show open');
});
});
</script>
<?php function menu_builder1($db, $parent_id) {
$sql = $db->prepare("SELECT * FROM menu WHERE status = 1 ORDER BY position ASC");
if($sql->execute()) {
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$array[$row['menu_sub_id']][] = $row;
}
main_menu1($array);
}
}
function main_menu1($array, $parent_id = false) {
if(!empty($array[$parent_id])) {
foreach ($array[$parent_id] as $item) {
if ($item['dropdown'] == false) {
echo '<li class="nav-item active"><a class="nav-link" href="' . $item['href'] . '">' . $item['name'] . '</a></li>';
}
elseif ($item['dropdown'] == true) {
echo '<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="dropdown2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . $item['name'] . '</a>';
sub_menu1($array, $item['menu_id']);
echo '</li>';
}
}
}
}
function sub_menu1($array = array(), $parent_id = false) {
if(!empty($array[$parent_id])) {
echo '<ul class="dropdown-menu" aria-labelledby="dropdown2">';
foreach ($array[$parent_id] as $item) {
if ($item['dropdown'] == false) {
echo '<li class="dropdown-item"><a href="' . $item['href'] . '">' . $item['name'] . '</a></li>';
}
elseif ($item['dropdown'] == true) {
echo '<li class="dropdown-item dropdown"><a class="dropdown-toggle" id="dropdown2-1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . $item['name'] . '</a>';
sub_sub_menu1($array, $item['menu_id']);
echo '</li>';
}
}
echo "</ul>";
}
}
function sub_sub_menu1($array = array(), $parent_id = false) {
if(!empty($array[$parent_id])) {
echo '<ul class="dropdown-menu" aria-labelledby="dropdown2-1">';
foreach ($array[$parent_id] as $item) {
if ($item['dropdown'] == false) {
echo '<li class="dropdown-item"><a href="' . $item['href'] . '">' . $item['name'] . '</a></li>';
}
}
echo "</ul>";
}
}
?>
<div class="navbar navbar-expand-md navbar-dark bg-dark mb-4" role="navigation">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<?=menu_builder1($db, 0)?>
</ul>
</div>
</div>
还有一些SQL信息
CREATE TABLE `menu` (
`menu_id` int(11) NOT NULL,
`menu_sub_id` int(11) NOT NULL,
`added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`status` int(1) NOT NULL DEFAULT '1',
`href` varchar(150) NOT NULL,
`class` varchar(150) NOT NULL,
`position` int(3) NOT NULL,
`name` varchar(150) NOT NULL,
`description` varchar(500) NOT NULL,
`dropdown` int(11) NOT NULL,
`sub_menu` int(1) NOT NULL,
`sub_sub_menu` int(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `menu`
ADD PRIMARY KEY (`menu_id`);
ALTER TABLE `menu`
MODIFY `menu_id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;