【问题标题】:PHP Bootstrap 4 navigation menu with sub-menu'sPHP Bootstrap 4 带有子菜单的导航菜单
【发布时间】:2023-03-06 16:44:01
【问题描述】:

原帖

我想使用 Bootstrap 4 在 PHP 中创建一个导航菜单。问题是 <li> 之一不正确(来自 dropdown 的那个,它不会成为下拉菜单,而只是一个普通的 @ 987654325@)。如果您想使用<ul><li> 创建一个普通菜单,则此代码可以正常工作,但使用引导程序,您需要在ID 为2<li> 上有一个nav-item dropdown,名为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>";
    }
}

我真的希望有人能帮我解决这个问题,我应该在数据库中添加一些东西以便它知道它是一个下拉列表吗?我认为我的代码太大而且太复杂,应该有一个更简单的方法,但我不知道如何。我想我需要一个完全不同的方法。如果你能在正确的方向上帮助我,那也很好。

还要感谢制作子菜单教程的人(在这里您还可以看到菜单是如何使用&lt;ul&gt;&lt;li&gt; 构建的,并且完全符合它需要做的事情,但不适用于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>

【问题讨论】:

    标签: php html pdo bootstrap-4


    【解决方案1】:

    我在数据库中添加了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;
    });
    

    【讨论】:

      【解决方案2】:

      我对 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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 2013-09-26
        • 2019-06-20
        • 1970-01-01
        • 2021-04-10
        相关资源
        最近更新 更多