dynamic multi level dropdown menu php sql - php

I have nav menu in html and i want to create a loop everything is fine but the item that have children echo twice! i know where is the problem but i can't figure out how to solve it :(
my sql table named menu
and this is my php:
$db = mysqli_connect('localhost', 'root', 'password', 'aftab');
<?php
$get = mysqli_query($db , "SELECT * from menu where parent_id is NULL");
while ($rowmenu = mysqli_fetch_assoc($get)) {
echo '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-656"><a href="'. $rowmenu['link'] . '" >' . $rowmenu['name'] .'</a>' ;
$id = $rowmenu['id'] ;
$check = mysqli_query($db , "SELECT * from menu where parent_id = '$id'");
if ( mysqli_num_rows($check) ) {
echo '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-656"><a href="'. $rowmenu['link'] . '" >' . $rowmenu['name'] .'</a>' ;
echo '<ul class="sub-menu">' ;
while ( $row2 = mysqli_fetch_assoc($check) ) {
echo '<li class="menu-item-302">' . $row2['name'] . '</li>' ;
}
echo '</ul>' ;
} else {
echo '</li>' ;
}
}
?>
and this the result:enter image description here
i know it happen because the father item that hold the sub menu's called in $get once and another time when it need other css class.i tried if , foreach , while and many things.
i need that item that holds submenus should have "menu-item-has-children" class otherwise its not show the sub menus.

When a menu item, have childrens then echo menu with menu-item-has-children class, otherwise echo a simple menu and move on.
<?php
$get = mysqli_query($db , "SELECT * from menu where parent_id is NULL");
while ($rowmenu = mysqli_fetch_assoc($get)) {
$id = $rowmenu['id'] ;
$check = mysqli_query($db , "SELECT * from menu where parent_id = '$id'");
$haveSubMenu = mysqli_num_rows($check);
if($haveSubMenu)
echo '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-656 menu-item-has-children"><a href="'. $rowmenu['link'] . '" >' . $rowmenu['name'] .'</a>' ;
else
echo '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-656"><a href="'. $rowmenu['link'] . '" >' . $rowmenu['name'] .'</a>' ;
if ($haveSubMenu)
{
echo '<ul class="sub-menu">' ;
while ( $row2 = mysqli_fetch_assoc($check) ) {
echo '<li class="menu-item-302">' . $row2['name'] . '</li>' ;
}
echo '</ul>' ;
} else {
echo '</li>' ;
}
}
?>

Here is see that Our Products from the database is printed twice.This is because you are fetching and echoing $row2['name'] twice but you can handle the first coming array by changing your SQL query.
Change your first SQL query to
$get = mysqli_query($db , "SELECT * from menu where parent_id is NULL AND name != 'OUR PRODUCTS'");
Querying this to database you will get all the NULL values in the array excluding OUR PRODUCTS and thus it will be echoed only once by the second query.

I tried the above to answer all is working only a few level dropdown menu.
If you want to really create your menu for multi-level dropdown as like tree structure just use the bellow function. for more detailing once go through
https://bootstrapfriendly.com/blog/dynamic-multi-level-dropdown-sticky-menu-in-php-mysql-using-bootstrap/
<?php
include_once("connection.php");
$query = "SELECT id, label, link, parent FROM menus ORDER BY sort ASC, label";
$result = mysqli_query($conn, $query) or die("database error:" . mysqli_error($conn));
// Create an array to conatin a list of items and parents
$menus = array(
'items' => array(),
'parents' => array()
);
// Builds the array lists with data from the SQL result
while ($items = mysqli_fetch_assoc($result)) {
// Create current menus item id into array
$menus['items'][$items['id']] = $items;
// Creates list of all items with children
$menus['parents'][$items['parent']][] = $items['id'];
//echo $items;
}
// function to create dynamic treeview menus
function createMenu($parent, $menu)
{
$html = "";
if (isset($menu['parents'][$parent])) {
// $html .= '<ul class="sina-menu sina-menu-right" data-in="fadeInLeft" data-out="fadeInOut">';
foreach ($menu['parents'][$parent] as $itemId) {
if (!isset($menu['parents'][$itemId])) {
$html .= "<li >
<a href='" . $menu['items'][$itemId]['link'] . "'>" . $menu['items'][$itemId]['label'] . "</a>
</li>";
}
if (isset($menu['parents'][$itemId])) {
$html .= "<li class='dropdown'>
<a class='dropdown-toggle' data-toggle='dropdown' href='" . $menu['items'][$itemId]['link'] . "'>" . $menu['items'][$itemId]['label'] . "</a>";
$html .= '<ul class="dropdown-menu">';
$html .= createMenu($itemId, $menu);
$html .= '</ul>';
$html .= "</li>";
}
}
// $html .= "</ul>";
}
return $html;
}

Related

Interrupt and return repetition within the while multiple times

I'm not new here but I also do not ask questions because whenever I have a problem I find a solution in questions related here in the forum or in blogs, but I did not have any success with this problem.
In a database I have the tables posts and categories that are related, and in a single MySQL query I am displaying the title of the posts within their categories. So far so good, everything working. However within the while loop structure the tag with the is-sub class can not be repeated. Is there any way to stop the repetition of this while and then repeat it again?
I thank you for your help
echo '
<nav class="navbar">
<ul>';
$sql = Query("SELECT * FROM posts INNER JOIN categories ON post_category = category_id ORDER BY post_category, post_title");
$is_category = NULL;
while ($row = mysqli_fetch_assoc($sql)) :
if ($row['post_category'] != $is_category) {
echo '<li class="has-sub">' . $row['category_title'] . '';
$is_category = $row['post_category'];
}
// stop loop
echo '<ul class="is-sub">';
// return loop
echo '<li>' . $row['post_title'] . '</li>';
// stop loop
echo '</ul>';
// return loop
echo '</li>';
endwhile;
echo '
</ul>
</nav>';
If I understood what you are trying to do, I think the code below would work. If the is_sub tag is really meant to show only once then this could work:
<?php
echo '
<nav class="navbar">
<ul>';
$sql = Query("SELECT * FROM posts INNER JOIN categories ON post_category = category_id ORDER BY post_category, post_title");
$is_category = NULL;
$issub = false;
while ($row = mysqli_fetch_assoc($sql)) :
if ($row['post_category'] != $is_category) {
echo '<li class="has-sub">' . $row['category_title'] . '';
$is_category = $row['post_category'];
echo '<ul class="is-sub">';
}
if(!$issub) {
echo '<ul class="is-sub">';
$issub = true;
}
echo '<li>' . $row['post_title'] . '</li>';
echo '</ul>';
echo '</li>';
endwhile;
echo '
</ul>
</nav>';
?>

Mega dropdown menu css for mysql database data

I want to make mega dropdown menu that comes from mysql database. Below is my php code. The code is working well. But the problem is I am unable to make mega dropdown menu for the code below.
I need the mega menu like the example here : https://bootsnipp.com/snippets/featured/bootstrap-mega-menu
My problem is how will I make more div with the below php code .
Plz help me the css for the mega drop down menu as shown above.
<?php
$sql = "SELECT id, product, parent_id, category_link FROM category ORDER BY parent_id, id";
$results = mysqli_query($conn,$sql) or die(mysqli_error()) ;
if($results)
{
while($result = mysqli_fetch_array($results))
{
$category['categories'][$result['id']] = $result;
$category['parent_cats'][$result['parent_id']][] = $result['id'];
}
}
function getCategories($parent, $category)
{
$html = "";
if (isset($category['parent_cats'][$parent]))
{
$html .= "<div id='wrapper'>";
$html .= "<ul class='mega-menu'>\n";
foreach ($category['parent_cats'][$parent] as $cat_id)
{
if (!isset($category['parent_cats'][$cat_id]))
{
$html .= "<li class='mega-menu-drop'>\n <a class='mega-menu-content' href='" . $category['categories'][$cat_id]['category_link'] . "'>" . $category['categories'][$cat_id]['product'] . "</a>\n</li> \n";
}
if (isset($category['parent_cats'][$cat_id]))
{
$html .= "<li class='mega-menu-drop'>\n <a class='mega-menu-content' href='" . $category['categories'][$cat_id]['category_link'] . "'>" . $category['categories'][$cat_id]['product'] . "</a> \n";
$html .= getCategories($cat_id, $category);
$html .= "</li> \n";
}
}
$html .= "</ul> \n";
$html .= "</div>";
}
return $html;
}
?>
<?php echo $data['category'] = getCategories(0, $category);?>
as of your comment. i guess you need some CSS.
this will work on mouse hover. but not on click like in your example:
.mega-menu-drop {
display:none
}
.mega-menu:hover .mega-menu-drop {
display:block
}

Make a Dynamic Drop Down Navigation system

I am trying to create a Dropdown Menu on my site, Ive hit a brick wall and cannot think on how to do it.
Basically i need to check 2-3 variables in a database and out put the correct data.
I have at the moment it checking if its an External Link or Not, and if it contains a submenu, but i can't get it to output the correct information.
Basically i want it to check if its a External or Non-External link, and if it has a submenu, if it has a submenu, to display the menu options underneath it. So say i have menu 1, 2 ,3, 4 and 2,4 has a submenu, i need them to list the other links under them. i have put in my database toplink_id (to represent which link this item should be under) sc_order (which will control the order the sublinks display in) also dropdown (which tells me if the menu has a submenu or not.)
Here is the start of my code
$sql = "SELECT label, url, ext, dropdown FROM content_pages WHERE top_nav='1' AND active='1' ORDER by page_order ASC";
$query = mysqli_query($dbc, $sql) or die (mysqli_error($dbc));
$menuDisplay .= '<div class="bg-2"><div class="container_12"><article class="grid_12"><nav><ul class="menu sf-js-enabled">';
while ($row = mysqli_fetch_array($query)) {
$url = $row["url"];
$nav_label = $row["label"];
$drop_down ='<ul><li>' . $nav_label . '</li></ul>';
if ($row["ext"] == 0 && $row["dropdown"] == 1){
$menuDisplay .= '<li>' . $nav_label . '' . $drop_down . '</li>';
}
elseif ($row["ext"] == 1 && $row["dropdown"] == 1){
$menuDisplay .= '<li>' . $nav_label . '' . $drop_down . '</li>';
}
elseif ($row["ext"] == 0){
$menuDisplay .= '<li>' . $nav_label . '</li>';
}
elseif ($row["ext"] == 1)
{
$menuDisplay .= '<li>' . $nav_label . '</li>';
}
}
$menuDisplay .= '</ul></nav></article></div></div></header>';
mysqli_free_result($query);
Best way I found to do this without using jQuery is use multidimensional Arrays.
// Create a multidimensional array to conatin a list of items and parents
$menu = array(
'items' => array(),
'parents' => array(),
);
// Builds the array lists with data from the menu table
while ($items = mysqli_fetch_assoc($query))
{
// Creates entry into items array with current menu item id ie. $menu['items'][1]
$menu['items'][$items['id']] = $items;
// Creates entry into parents array. Parents array contains a list of all items with children
$menu['parents'][$items['parent']][] = $items['id'];
}
// Menu builder function, parentId 0 is the root
function buildMenu($parent, $menu)
{
$html = "\n";
if ( isset($menu['parents'][$parent]) )
{
$html .= "";
foreach ($menu['parents'][$parent] as $itemId)
{
if(!isset($menu['parents'][$itemId]) && $menu['items'][$itemId]['ext'] == 0)
{
$html .= "<li>\n <a href='../pages/".$menu['items'][$itemId]['link']."'>".$menu['items'][$itemId]['label']."</a>\n</li> \n";
}
else
if(!isset($menu['parents'][$itemId]) && $menu['items'][$itemId]['ext'] == 1)
{
$html .= "<li>\n <a href='../".$menu['items'][$itemId]['link']."'>".$menu['items'][$itemId]['label']."</a>\n</li> \n";
}
if(isset($menu['parents'][$itemId]))
{
$html .= "<li>\n <a href='../pages/".$menu['items'][$itemId]['link']."'>".$menu['items'][$itemId]['label']."<span class='arrow-down'></span></a> \n";
$html .= "<ul style='border-radius: 0px 0px 6px 6px'> \n";
$html .= buildMenu($itemId, $menu);
$html .= "</ul> \n";
$html .= "</li> \n";
}
}
$html .= "\n";
}
$html .= "";
return $html;
}

Hierarchical tree menu - PHP / MySQL

In working on a dynamic menu w/ CRUD I have been having some trouble with the finishing touches. It works, but there are some extra tags getting inserted where there shouldn't be and can't figure out how to clean it up before I share it with the world. I used this as a starting point, then changed it to work with an accordion menu (http://www.phpro.org/tutorials/Simple-Mysql-PHP-Menu.html).
Below is the data from the table (I changed the names on the first 2 fields to get it to fit in the SO format from menu_item_id to id, and from menu_parent_id to pid).
id pid menu_item_name menu_url sortorder status
1 0 Settings 0 ACTIVE
2 5 Grid Demo grid.php ACTIVE
3 5 setGridOptions gridoptions.php ACTIVE
4 1 Menu Items adminmenu.php 1 ACTIVE
5 0 Grid Settings 100 ACTIVE
6 1 General Settings settings.php 100 ACTIVE
Here is the PHP that connects to the mysql database and creates the hierarchical tree array to make it work:
include 'db.php';
$sql = "SELECT * FROM menu_items WHERE status = \"ACTIVE\" ORDER BY sortorder, menu_item_name";
$query = $db->query($sql);
while($data = $query->fetch(PDO::FETCH_ASSOC))
// loop over the results
{
// Assign by reference
$thisref = &$refs[ $data['menu_item_id'] ];
// add the the menu parent
$thisref['menu_item_id'] = $data['menu_item_id'];
$thisref['menu_parent_id'] = $data['menu_parent_id'];
$thisref['menu_item_name'] = $data['menu_item_name'];
$thisref['menu_url'] = $data['menu_url'];
// if there is no parent id
if ($data['menu_parent_id'] == 0)
{
$list[ $data['menu_item_id'] ] = &$thisref;
}
else
{
$refs[ $data['menu_parent_id'] ]['children'][ $data['menu_item_id'] ] = &$thisref;
}
}
function create_list( $arr )
{
$html = "";
foreach ($arr as $key=>$v)
{
if ($v['menu_parent_id'] == '0')
{
$html .= '<a class="menuitem submenuheader" href="'. $v['menu_url'] .'">'.$v['menu_item_name']."</a>\n";
$html .= "<div class=\"submenu\">\n<ul>\n";
$html .= "<li>" . create_list($v['children']) . "</li>";
$html .= "</ul>\n";
}
else{
$html .= '<li><a id="' . $v['menu_item_id'] . '">'.$v['menu_item_name']."</a></li>\n";
}
}
$html .= "</div>\n";
return $html;
}
echo "<div class=\"glossymenu\">";
echo create_list( $list );
echo "</div>";
When I run it, it outputs the following:
<div class="glossymenu"><a class="menuitem submenuheader">Settings</a>
<div class="submenu">
<ul>
<li><li><a id="4">Menu Items</a></li>
<li><a id="6">General Settings</a></li>
</div>
</li></ul>
<a class="menuitem submenuheader" href="">Grid Settings</a>
<div class="submenu">
<ul>
<li><li><a id="2">Grid Demo</a></li>
<li><a id="3">setGridOptions</a></li>
</div>
</li></ul>
</div>
</div>
As you can see there are extra <li> tags, the </ul> is in the wrong
spot (should be after the </div>) Other than that, it is working great.
The other thing I can't figure out is if I have a root menu item with no children, I would love it to have a different output like
<a id="8">No Children Menu Item</a>
Instead of:
<a class="menuitem submenuheader">No Children Menu Item</a>
The second example would create the make it show up the little (+/-) for expanding and contracting and wouldn't allow me to click on it. For clarification on the <a> tags, I am using javascript to do a .get() based off the id which is why there is no href or url shown.
UPDATE
It is working correctly and I posted it on Github for anyone that wants it.
https://github.com/ajhalls/php-accordian-menu
Try this :
<?php
include 'db.php';
$sql = "SELECT * FROM menu_items WHERE status = 'ACTIVE' ORDER BY pid ASC, sortorder ASC, menu_item_name ASC";
$query = $db->query($sql);
$menu_items = array();
while($data = $query->fetch(PDO::FETCH_ASSOC)) {
if($data['pid'] == 0) {
$menu_items[$data['id']] = array();
$menu_items[$data['id']]['id'] = $data['id'];
$menu_items[$data['id']]['name'] = $data['menu_item_name'];
$menu_items[$data['id']]['url'] = $data['menu_url'];
$menu_items[$data['id']]['children'] = array();
} else if($data['pid'] != 0) {
$tmp = array();
$tmp['id'] = $data['id'];
$tmp['name'] = $data['menu_item_name'];
$tmp['url'] = $data['menu_url'];
array_push($menu_items[$data['pid']]['children'],$tmp);
unset($tmp);
}
}
function create_list($arr)
{
$html = "";
foreach($arr as $key => $value) {
if(count($value['children']) > 0) {
$html .= ' <a class="menuitem submenuheader" href="'. $value['url'] .'">'.$value['name'].'</a>
<div class="submenu">
<ul>';
foreach($value['children'] AS $child) {
$html .= ' <li>
<a id="'.$child['id'].'">'.$child['name'].'</a>
</li>';
}
$html .= ' </ul>
</div>';
} else{
$html .= ' <a id="'.$value['id'].'">'.$value['name'].'</a>';
}
}
return $html;
}
echo "<div class=\"glossymenu\">";
echo create_list($menu_items);
echo "</div>";
?>

position the result base on row number in mysql

I have this function (refer below)
function showMenu(){
$result = mysqli_query($con,"SELECT * FROM user_menu");
$menu = '<nav id="main-menu"><ul class="menuwrapper extend">';
while($row = mysqli_fetch_array($result))
{
$menu .= '<li class="' . $row['status'] . '">' . $row['name'] . '</li>';
}
$menu .= '</ul></nav>';
return $menu;
}
and my database table is structured as follows (refer below)
id(BigInt 100, AUTO_INCREMENT, PRIMARY)
name(text, utf8_general_ci)
url(varchar 100, utf8_general_ci)
status(text, utf8_general_ci)
key(int 30)
The contents of that table are (refer
below)
id = "1", name = "Post", url = "http://localhost/gadgetmarket/admin/index.php", status="default", key = "0"
id = "2", name = "Pages", url = "http://localhost/gadgetmarket/admin/pages.php", status="parent", key = "1"
id = "3", name = "Menus", url = "http://localhost/gadgetmarket/admin/menus.php", status="parent", key = "2"
id = "4", name = "Theme", url = "http://localhost/gadgetmarket/admin/theme.php", status="parent", key = "3"
Now, my question is how could I output the result base on there keys number that each menu has on? my expected output base on what im trying to achieve from the datas above is (refer below)
<nav id="main-menu">
<ul class="menuwrapper extend">
<li class="default">
Post
</li>
<li class="parent">
Pages
</li>
<li class="parent">
Menus
</li>
<li class="parent">
Theme
</li>
</ul>
</nav>
As you can see the output was arrange base on keys order. Any recommendations, suggestions and ideas will be greatly appreciated. Thanks in advance.
For a start, you're not declaring the connection global in your function
function showMenu(){
global $con; // SIMPLY ADD THIS LINE
$result = mysqli_query($con,"SELECT * FROM user_menu");
$menu = '<nav id="main-menu"><ul class="menuwrapper extend">';
while($row = mysqli_fetch_array($result))
{
$menu .= '<li class="' . $row['status'] . '">' . $row['name'] . '</li>';
}
$menu .= '</ul></nav>';
return $menu;
}
and you can use ORDER BY to fetch the data the way you want it
SELECT * FROM user_menu ORDER BY key ASC

Categories