Dynamic Drop Down Menu and submenu php mysql - php

I have a menu that needs to be created dynamically from the database.
need to have menu and submenu
for example (wht i want):
<ul class="dropdown">
<li>Link 1 </li>
<li>Link 2 </li>
<li>Link 3 </li>
<li>Link 4
<ul class="sub_menu">
<li>Link 4 - 1</li>
<li>Link 4 - 2</li>
<li>Link 4 - 3</li>
</ul>
</li>
<li>Link 5</li>
<li>Link 6 </li>
</ul>
below is the code i used for menu using function i want submenu as well
function listMenu(){
$ans = $this->select("cat_id,cat_name","s_category","1");
if(is_array($ans)){
foreach($ans as $val){
echo
"<li><a href=\"post-summary.php?cid=$val[0]\" >$val[1]</a></li>";
}
}
else{
echo "";
}
}
database is as follows:-
CREATE TABLE IF NOT EXISTS `s_category` (
`cat_id` int(11) NOT NULL AUTO_INCREMENT,
`cat_name` varchar(15) NOT NULL,
`cat_uid` int(2) NOT NULL,
`cat_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`cat_parent` int(11) DEFAULT '0',
`cat_sort` int(11) DEFAULT NULL,
`cat_delete` int(1) DEFAULT '0',
PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

You need to have a column, let we name it parentId in the s_category table.
Example values in there:
catId,catName,parentId
1,Vehicles,null
2,Planes,null
3,Cars,1
4,Bicycles,1
So your structure will be like:
- Vehicles
- Cars
- Bicycles
- Planes
You'll need to get the data like this (to be considered as pseudocode):
$topLevelItems = (select catId, catName from s_category where parentId is null)
foreach($topLevelItems as $item) {
echo '$item["catName"]';
$subItems = (select catId, catName from s_category where parentId=$item['catId'])
foreach($subItems as $subItem) {
echo '$subItem["catName"]';
}
}
You need to re-write the SQL part to match your case. This will work if you have just one inner level, e.g. no sub-sub-menus. If you plan to use sub-sub-menus you'll need recursive function.

as far as menus are concerned storing the submenus as a comma seperated values in the database would come handy.
ie consider a table with id,menus,submenus(several submenus seperated by a comma).
function listMenu(){
$ans = $this->select("menus,submenus");
if(is_array($ans)){
foreach($ans as $val){
echo "<li><a href=\"post-summary.php?cid=$val[0]\" >$val[0]</a>"; //menus
$submenu = explode(",",$val[1]);
foreach($submenu as $values){
echo "<li><a href=\"post-summary.php?cid=$val[0]&proname=$values\" >$values</a></li>"; // submenus
}
echo "</li>";
}
}
}
try this
$con = db_connect();
$str = "select menus,submenus from your_tabel ";
$result = mysql_query($str,$con);
while($arr = mysql_fetch_array($result))
{
echo "<li><a href=\"post-summary.php?cid=$arr[0]\" >$arr [0]</a>"; //menus
$submenu = explode(",",$arr [1]);
//make sure you have several sub-menus else use a if condition here to avoid foreach error
foreach($submenu as $values){
echo "<li><a href=\"post-summary.php?cid=$arr[0]&proname=$values\" >$values</a></li>"; // submenus
}
echo "</li>";
}
this works fine for me just tested now
comment if working.
comment if not-working.

created your database and write function with code and change parameters
function getAllFrom($field, $table,$where = NULL, $and = NULL , $orderfield, $ordering = "DESC") {
global $con;
$getAll = $con->prepare("SELECT $field FROM $table where $where $and ORDER BY $orderfield $ordering");
$getAll->execute();
$all = $getAll->fetchAll();
return $all;}
<ul>
<?php
$allCats = getAllFrom("*", "categories", "parent = 0", "" , "cat_id", "ASC");
foreach ($allCats as $cat) { ?>
<li>
<?php
echo '<a href="categoreis.php?pagename=' . str_replace(' ', '-', $cat['name_cat']) . '&pageid=' . $cat["cat_id"] . '">
' . $cat['name_cat'] . '
</a>';
?>
<ul class="sub-menu[enter image description here][1]">
<?php
$catsub = $cat['cat_id'];
$SubCats = getAllFrom("*", "categories", "parent = {$catsub}", "" , "cat_id", "ASC");
foreach ($SubCats as $sub) { ?>
<li>
<?php
echo '<a href="categoreis.php?pagename=' . $sub['name_cat'] . '&pageid=' . $sub["cat_id"] . '">
' . $sub['name_cat'] . '
</a>';
?>
</li>
<?php }
?>
</ul>
</li>
<?php }
?>
</ul>

Related

Different header navigation by specified user right values from SQL database to PHP (CMS)

I am having trouble making a PHP code. The PHP code a header navigation. In this header, It will show different headers for different users. I had added a column in my SQL database called "groups". I had added the default "0" as a INT. So when users make an account, It sets the "groups" to value 0.
In my admin panel, I have a table where you can edit the value on the groups. Users value is "0" and Admins value is "1"
The part I am stuck on is actually making the code to work. I tried to research on my issue but I could not find any solution.
Here is the code:
<?php
include('authCheck.php');
include('dbCredentials.php');
$group = isset($_GET['group']);
// Query
$sql = "SELECT * FROM AccountInfo WHERE group = :group";
$cmd = $conn->prepare($sql);
$cmd->bindParam(':group', $group, PDO::PARAM_INT);
// Run query
$cmd->execute();
$groups = $cmd->fetch(PDO::FETCH_ASSOC);
if ($groups['group'] < 0) {
echo '<li>Home </li>
<li>Edit List </li>
<li>Logout </li>';
} else if ($groups['group'] < 1) {
echo '<li>Admin Panel </li>
<li>Home </li>
<li>Logoff </li>';
} else {
echo '<li>Login </li>
<li>SignUp </li>';
}
?>
Please help, thank you! :)
EDIT
Here is the SQL DB
CREATE TABLE AccountInfo
(
user_id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
email VARCHAR(50),
password CHAR(128),
group INT(2) DEFAULT '0'
);
The USER_ID is used to identify each user by ID.
Easy peasy...change to:
if ($groups['group'] == 0) {
echo '<li>Home </li>
<li>Edit List </li>
<li>Logout </li>';
} else if ($groups['group'] == 1) {
echo '<li>Admin Panel </li>
<li>Home </li>
<li>Logoff </li>';
} else {
echo '<li>Login </li>
<li>SignUp </li>';
}

recursive php category tree extended

I have been searching all over the forum but could not locate the answer to my specific question. I hope you can help me, for it has taken me A LOT of time to figure this out as a beginning PHP programmer.
I have a page that listens to this URL : .../.../edit_cat.php?id=24
I want to have a nice category tree. I have accomplished this, but I want all categories with no children to be a link to page post.php and all parent that do have children to be a link but only to show the other categories. Some sort of dropdown menu you might call it. So no children is post.php and if has children then drop the rest of children down. I hope this makes it clear...This is whay I have so far. It works as a tree but not how I wish it to be:
<h2>This is the current category tree</h2>
<?php
category_tree(0);
function category_tree($catid){
include '../config/connect.php';
$result = $db->prepare("SELECT * FROM categories WHERE parent_id = '".$catid."'");
$result->execute();
while($row = $result->fetch(PDO::FETCH_ASSOC)):
$i = 0;
if ($i == 0){ echo '<ul class="cattree">';}
echo '<li>' . $row['cat_title'] . '';
category_tree($row['cat_id']);
echo '</li>';
$i++;
if ($i > 0){ echo '</ul>'; }
endwhile;
}
?>
My table of categories looks like this:
cat_id | cat_title | parent_id
1 some_title 0
2 some_title 1
3 title! 2
4 main_title 0
5 titellos! 4
Here is something I did last year, a query returns each line, with the idx, parent_idx and label of the line.
First call:
print_list(1, 0, $lines);
Function:
function print_list($parent, $level, $ar) {
$children = filter_by_parent($parent, $ar);
if (empty($children)) {
return;
}
echo '<ul>';
foreach ($children as $child) {
include PATH_PUBLIC . 'clients/simili/line.php';
print_list($child['Child_Idx'], ($level + 1), $ar);
echo '</li>';
}
echo '</ul>';
}
Second function:
function filter_by_parent($parent_id, $ar){
$retval = array();
foreach($ar as $a) {
if ($a['Parent_Idx'] == $parent_id) {
$retval[] = $a;
}
}
return $retval;
}
And the html called in the function:
<li class="no" data-id="<?php echo $child['Child_Idx']; ?>" data-parent-id="<?php echo $child['Parent_Idx']; ?>">
<i class="fa fa-plus-square-o"></i>
<i class="fa fa-minus-square-o"></i>
<span class="name">
<label><?php echo $child['Child_Name']; ?></label>
<i class="fa fa-book" title="Détails de l'Unité d'Organisation"></i>
</span>
<div class="chiffres">
<span class="inscrits"><?php echo $child['Nb_Collab']; ?></span>
<span class="etp-collab"><?php echo $child['ETP_Collab']; ?></span>
<span class="etp-postes"><?php echo $child['ETP_Postes']; ?></span>
<span class="etp-unit"><?php echo $child['ETP_Unit']; ?></span>
</div>
Ok, I don't know anything about PHP, but here's how you can add a "HasChildren" column to your sql query:
SELECT c.*,
CASE
WHEN EXISTS(SELECT * FROM Categories c1 WHERE c1.parent_id=c.cat_id) THEN 1
ELSE 0
END AS HasChildren
FROM Categories c
WHERE ParentID = #CatID

display multilevel database driven menu in php

I want to display a database driven Multilevel menu and below is what I have tried so far, but I am not getting the result as desired. Can any one help me to fix this. the output I am getting is only the main menu with parent id as 0, but not the sub menu items.
<?php
include('system/connection.php');
?>
<?php
//select all rows from the main_menu table
$q = "SELECT * FROM catelogue WHERE cat_visibility = '1'";
$r = mysqli_query($dbc, $q);
echo "<ul class='dropdown'>";
while ($rows = mysqli_fetch_assoc($r)) {
if ($rows['cat_parentid'] == 0) {
echo "<li><a href='#'>" . $rows['cat_name'] . "</a>";
echo "<ul>";
foreach ($rows as $item) {
if ($item['cat_parentid'] == $rows['cat_id']) {
echo "<li><a href='#'>" . $item['cat_name'] . "</a>";
echo "</li>";
}
}
echo "</ul>";
echo "</li>";
}
}
echo "</ul>";
?>
My Database structure is
-----------------------------------------
| cat_id | cat_name | cat_parentid |
-----------------------------------------
| 1 | Home | 0 |
| 2 | About | 0 |
| 3 | Contact | 0 |
| 4 | History | 2 |
| 5 | Services | 2 |
-----------------------------------------
Desired Output I want:
<ul class="dropdown">
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a>
<ul>
<li><a href='#'>History</a></li>
<li><a href='#'>Services</a></li>
</ul>
</li>
<li><a href='#'>Contact</a></li>
</ul>
Here is a recursive solution.
The code is fully commented.
There are two useful checks in the processMenuEntry routine that can conveniently be done so that you can decide if you want different actions to happen.
Check whether the 'current' 'entry' is the 'root' node.
$isRoot = $currentEntry['cat_id'] == 0; // do 'First time' processing
Check whether the current 'entry' has a 'submenu'.
if (!empty($subMenu)) { ...
Q29910284-display-multilevel-database-driven-menu.php
The code:
Database connection:
$DB_HOST = "localhost";
$DB_USER = "test";
$DB_PASSWORD = "test";
$DB_TO_USE = "testmysql";
$dbc = new mysqli($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_TO_USE);
Submenu Query:
/** -----------------------------------------------------------------
* Select all the menu entries for a given entry Id
*
* Note: it is safe to do 'parameter substitution' rather than using
* 'prepared queries' with placeholders as this 'entry Id' never
* comes from an external source.
*
* #param mysqli $dbc
* #param integer $currentEntryId
* #return array of menu entries
*/
function selectSubMenu($currentEntryId, $dbc)
{
$sql = "SELECT cat_id, cat_name, cat_parent_id
FROM catalogue
WHERE cat_parent_id = {$currentEntryId}
ORDER BY cat_id";
$resultSet = mysqli_query($dbc, $sql);
return $resultSet->fetch_all(MYSQLI_ASSOC);
}
Process Current Menu Entry:
/** --------------------------------------------------------------------------
* Process the current menu enty - it will return a complete menu as HTML
*
* These needs to know whether the current entry has a submenu and
* will therefore need to generate an 'unordered list' for the current entry.
*
* Alas, it also has to not display the 'list item text' for the 'root' entry
* but process the 'submenu'.
* This complicates the <li> current entry text generation slightly.
*
* #param array $currentEntry - one row
* #param array $subMenu - many rows - may be empty
* #param mysqli $dbc - database connection
* #return string - the HTML for the menu
*/
function processMenuEntry($currentEntry, array $subMenu, $dbc) {
$outMenu = '';
$isRoot = $currentEntry['cat_id'] == 0; // do 'First time' processing
// display the current entry text as a 'list item'
$outMenu .= !$isRoot ? "<li><a href='#'>" . $currentEntry['cat_name'] . "</a>" : '';
// does it have a submenu...
if (!empty($subMenu)) { // we need to add a complete submenu of <ul> ... </ul>
// Start of the submenu as an unordered list -- decide what is required
if ($isRoot) {
$outMenu .= '<ul class="dropdown">';
}
else {
$outMenu .= '<ul>';
}
// Display each entry of the submenu as a 'list item'
foreach ($subMenu as $submenuEntry) {
$outMenu .= processMenuEntry($submenuEntry,
selectSubMenu($submenuEntry['cat_id'], $dbc),
$dbc);
}
// close the current submenu - terminate the unordered list
$outMenu .= '</ul>';
}
// terminate the current list item
$outMenu .= !$isRoot ? '</li>' : '';
return $outMenu;
};
Process all the menu entries:
/* -------------------------------------------------------------------
* Process all the menu entries
*
* We need a complete menu 'tree' that includes a 'root' which is not provided
* in the database. I think it should be. Whatever, i need one.
*
* Initializing a 'tree walk' i always find 'interesting' ;-/
*/
$root = array('cat_id' => 0, 'cat_name' => '', 'cat_parent_id' => 0);
// build the output menu
$outMenu = processMenuEntry($root,
selectSubMenu($root['cat_id'], $dbc),
$dbc);
// wrap it in a <div>
$htmlMenu = '<div style="border: 1px solid red">'
. $outMenu
.'</div>';
?>
Output the generated HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test Recursive Menu Builder</title>
</head>
<body>
<?= $htmlMenu ?>
</body>
</html>
The generated HTML
<!DOCTYPE html>
<html>
<head>
<title>Test Recursive Menu Builder
</title>
</head>
<body>
<div style="border: 1px solid red">
<ul class="dropdown">
<li>
<a href='#'>Home</a>
</li>
<li>
<a href='#'>About</a>
<ul>
<li>
<a href='#'>History</a>
</li>
<li>
<a href='#'>Services</a>
</li>
</ul>
</li>
<li>
<a href='#'>Contact</a>
</li>
</ul>
</div>
</body>
</html>
What you call $rows is actually one row. Then, in the foreach ($rows as $item) loop, it iterates through the columns of this row. So, there is no $item['cat_parentid']. Try to see the output of the $rows and $item with var_dump().
A draft idea of one possible solution that comes to my mind is to first iterate through the result rows and save the sub items in a parent item (note: some array initializations would have to be added here):
while ($row = mysqli_fetch_assoc($r)) {
$menuItems[$row['cat_id']] = $row;
$parentId = $row['cat_parentid'];
$menuItems[$parentId]['sub_items'][] = $row['cat_id'];
}
And then iterate through the $menuItems array generating output, recursion would be great for this.
Also, ordering the sql results would be beneficial, to be sure that top menu items come first:
"SELECT * FROM catelogue WHERE cat_visibility = '1' ORDER BY cat_parentid ASC";

php mysql : How to list two tables with related data?

I had a simple tree structure output question,
In the beginning I use two mysql_query, one is to get the pro_class data, include pro_class.cid , and to query next table by cid, like:
mysql_query("select * from pro_class ");
mysql_query("select * from pro where cid='pro_class.cid' ");
but I want to using one query,how can I accomplish?
table: pro_class
cid  title  time
1  PEOPLE  2013/8/31
4  CAR   2013/8/30
7  Music  2014/7/10
table: pro
id  cid  title  content  time
1  1  Mark xxxx 2010/8/31
2  4  BMW xxxx 2012/2/12
3  1  Joe xxxx 2015/1/31
4  7  sweet xxxx 2013/8/22
5  1  KEN xxxx 2010/1/31
The structure should be
PEOPLE
-Mark
-Joe
-KEN
CAR
-BMW
Music
-sweet
I want to the Html output can like this (by php+mysql)
<ul>
<li class="">PEOPLE</li>
<ul class="sub">
<li><a title='Mark' href='?id=1'>Mark</a></li>
<li><a title='Joe' href='?id=3'>Joe</a></li>
<li><a title='KEN' href='?id=5'>KEN</a></li>
</ul>
<li class="">CAR</li>
<ul class="sub">
<li><a title='BMW' href='?id=2'>BMW</a></li>
</ul>
<li class="">Music</li>
<ul class="sub">
<li><a title='sweet' href='?id=4'>sweet</a></li>
</ul>
</ul>
How do I to coding sql?
$rst = mysql_query("select ?????? ");
while($row = mysql_fetch_object($rst)){
echo <<<EOD
<ul>
<li class="">{$row->pro_class.title}</li>
<ul class="sub">
<li><a title='{$row->pro.title}' href='?id={$row->pro.id}'>{$row->pro.title}</a></li>
</ul>
</ul>
EOD;
}
You can try this approach. It uses group_concat.
<?php
$query = "select pc.title as title, group_concat(p.title) as inner_titles FROM pro_class pc LEFT JOIN pro p ON p.cid=pc.cid GROUP BY p.cid ORDER BY p.title";
$result=mysqli_query($query);
print "<ul>";
while($res=mysqli_fetch_array($result)) {
print "<li>" . $res['title'] . "</li>";
$arr = explode(",",$res['inner_titles']);
if(count($arr)>0) {
print "<ul>";
foreach($arr as $val) {
print "<li>" . $val . "</li>";
}
print "</ul>";
}
}
print "</ul>";
?>
You can use a mysql function called group_concat which will merge a number of rows into a string that is delimited by something you choose.
The following will get you most of the way to getting what you want - you can probably work out the display part on your own though.
select
pro_class.title,
GROUP_CONCAT(pro.title SEPARATOR ',') AS listItems
from
pro_class
left outer join pro
on pro_class.cid=pro.cid
group by
pro_class.title

Multilevel menu from database records

I need some help with PHP. I have a multilevel css menu that works fine, but now I want to generate according to the records from a database.
The menu Code:
<div id="page-wrap">
<ul class="dropdown">
<li>Link 1 </li>
<li>Link 2 </li>
<li>Link 3 </li>
<li>Link 4
<ul class="sub_menu">
<li>Link 4 - 1</li>
<li>Link 4 - 2</li>
<li>Link 4 - 3</li>
</ul>
</li>
<li>Link 5</li>
<li>Link 6 </li>
</ul>
</div>
In the database every record has a field called main_manu which makes it a main link if the value of this field is Yes, and if the value is No then it has another field (sub_menu) which says the parent menu in which this link should be placed.! See the screenshot.
DB Fields
SO, now I don't know how to do the php piece that will get the records and if the value of the main_menu is yes, it will create a top level menu, and if the value of main_menu is no, it will create a sub level menu according to the value of sub_menu field.
Thanks a lot
UPDATE
This is the code I have so far and it works. It would be nice if I could use a single query instead of multiple nested queries.
<div id='page-wrap'>
<ul class='dropdown'>
<?
$sql_menu = "SELECT * FROM content WHERE visible = '1' and main_menu='yes' ";
$result_menu = mysql_query($sql_menu);
while($row = mysql_fetch_assoc($result_menu))
{
$id=$row['id'];
$menu_top=$row['menu_name'];
$menu_url=$row['menu_url'];
print "<li><a href='$menu_url'>$menu_top</a>";
$sql_sub = "SELECT * FROM content WHERE sub_menu = '$menu_url' ";
$result_sub = mysql_query($sql_sub);
$num_rows = mysql_num_rows($result_sub);
while($row = mysql_fetch_assoc($result_sub))
{
$id=$row['id'];
$menu_sub=$row['menu_name'];
$sub_url=$row['menu_url'];
If ($num_rows != 0)
{
print "<ul class='sub_menu'>
<li><a href='$sub_url'>$menu_sub</a></li>
</ul>";
}
}
print "</li>";
}
?>
</ul>
</div>
The code for this would be something like the following (This will need to be changed for whatever way you interact with the database etc.):
// Here we do a query to get all the rows from the table
$db_result = db_execute_query('SELECT * FROM `menu_table` ORDER BY `order_no`');
// Here we take the rows and put it into a structured array
$items = array();
$hierarchy = array('' => array());
while ($row = db_fetch_row($db_result)) {
$items[$row['menu_name']] = $row['menu_name_en'];
if ($row['main_menu'] == 'yes') {
$hierarchy[''][] = $row['menu_name'];
} else {
if (!isset($hierarchy[$row['sub_menu']]) {
$hierarchy[$row['sub_menu']] = array();
}
$hierarchy[$row['sub_menu']][] = $row['menu_name'];
}
}
// Here we define a recursive function to run through our $hierarchy array;
function show_menu($name = '') {
if (isset($hierarchy[$name])) {
if ($name == '') {
echo '<ul class="dropdown">';
} else {
echo '<ul class="sub_menu">';
}
foreach ($hierarchy[$name] as $sub) {
echo '<li>' . $items[$sub] . '';
show_menu($sub);
echo '</li>';
}
echo '</ul>';
}
}
// Here we execute the recursive function on the main menu
show_menu('');
Try to understand what I'm doing here instead of just implementing it verbatim. Once you get to know recursive functions, a whole new world can open for you.
Also note that your db table could be changed to make this code simpler
I think these link will help you out. if not please let me know i will give you the code
http://board.phpbuilder.com/showthread.php?10337808-how-to-create-menu-submenu-subsubmenu-using-php-mysql
http://www.sitepoint.com/forums/showthread.php?718237-how-to-create-dynamic-menu-and-submenu-using-php-and-mysql

Categories