带有子菜单

时间:2018-04-09 12:00:53

标签: php html5 pdo bootstrap-4

原始帖子

我想在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">
        &#9776;
    </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>

2 个答案:

答案 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">
        &#9776;
    </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;