dynamic custom menu php - php

trying to get some thing like that dynamically
<ul>
<li>Home</li>
<li>About Us</li>
<li>Academics
<ul style="overflow: hidden; display: block; height: 0px; z-index: 51; opacity: 0.00980392;">
<li>Bs Computer Science</li>
<li>Diplomas (DIT & DCHE)</li>
<li>MBAIT</li>
</ul>
</li>
<li><a class=" " href="#">College</a>
</ul>
the code is
<?php
//========================================================
$result = mysql_query(" SELECT id, parentId, name
FROM
menu
ORDER BY
parentId, name");
$menuData = array(
'items' => array(),
'parents' => array()
);
while ($menuItem = mysql_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
function buildMenu($parentId, $menuData)
{
$html = '';
if (isset($menuData['parents'][$parentId]))
{
$html = '<ul id="main_menu">';
foreach ($menuData['parents'][$parentId] as $itemId)
{
$html .= '<li>' . $menuData['items'][$itemId]['name'];
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
//=======================================================
?>
above code is showing only first parents elements in the menu and the remaing elements are not showing.. the menu is not working correctly becoz of the class id is not given in the ul tag.. and by writing this
echo '<ul id="main_menu">';
// output the menu
echo buildMenu(0, $menuData);
echo "</ul>";
it shows nothing in the menu

Ok, try this:
<?php
//========================================================
$result = mysql_query(" SELECT id, parentId, name, link
FROM
menu
ORDER BY
parentId, name");
$menuData = array(
'items' => array(),
'parents' => array()
);
while ($menuItem = mysql_fetch_assoc($result)) {
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
function buildMenu($parentId, $menuData)
{
$html = '';
if (isset($menuData['parents'][$parentId]) && count( $menuData['parents'][$parentId] ) > 0 ) {
if( $parentId == "0" ){
$html = '<ul id="main_menu">';
}else{
$html = '<ul id="sub_menu">';
}
foreach ($menuData['parents'][$parentId] as $itemId) {
$html .= '<li>';
$html .= strlen($menuData['items'][$itemId]['link']) > 2?
''.$menuData['items'][$itemId]['name'].'':
$menuData['items'][$itemId]['name'];
$html .= buildMenu($itemId, $menuData);
$html .= "</li>";
}
$html .= '</ul>';
} else {
$html .= '<li>' . $menuData['items'][$parentId]['name'].'</li>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
//=======================================================
?>

Related

find last child in recursive function

recursive function
im trying to achieve above condition.
i have successful list parent and multi-level child title in tab title section
Now in Tab Content im trying to list content for the title listed in Tab title
In Tab Content if parent have multi-level child then only last child content should display but if parent does have any child then parent content should display
But im getting content for all title parent as well as nested child here i want last child content only but if parent does have child then parent content should be displayed
how to check if parent have any child, if parent have child then display content for last child only, if parent doesn’t have child then display parent content
Code for displaying Multi-level-nested child Title in Tab Title
$categoryMulti = array(
'categories' => array(),
'parent_cats' => array()
);
$sql = "SELECT `id`, `parent_id`, `name`, `content` FROM categories";
$query = $conn->query($sql);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$categoryMulti['categories'][$row['id']] = $row;
$categoryMulti['parent_cats'][$row['parent_id']][] = $row['id'];
}
//title for tabs
function listCategoryTree($parent, $category)
{
$css_class = ($parent == 0 ? "parent" : "child");
$html = '';
if (isset($category['parent_cats'][$parent])) {
$html .= '<ul class="im-'.$css_class.'">'."\n";
foreach ($category['parent_cats'][$parent] as $cat_id) {
if (!isset($category['parent_cats'][$cat_id])) {
$html .= '<li id="">
<a href="" data-cap= "'.$css_class.'-'.$cat_id.'">'
. $category['categories'][$cat_id]['name'] .
'</a>';
'</li>'."\r";
} else {
$html .= '<li id="">
<a href="" data-cap= "'.$css_class.'-'.$cat_id.'">'
. $category['categories'][$cat_id]['name'] .
'</a> <span>arrow icon </span>'."\r";
$html .= listCategoryTree($cat_id, $category);
$html .= '</li>'."\r";
}
}
$html .= '</ul>'."\n";
}
return $html;
}
Code trying to display last child content if parent have multi-level-nested child and if parent does have any child display parent content
but its display content for all nested-child and parent content too.
//content for tabs
$contentTab = array(
'contentCat' => array(),
'contentChild' => array()
);
$sql = "SELECT `id`, `parent_id`, `name`, `content` FROM categories";
$query = $conn->query($sql);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$contentTab['contentCat'][$row['id']] = $row;
$contentTab['contentChild'][$row['parent_id']][] = $row['id'];
}
function listContentTree($parent, $category)
{
$css_class = ($parent == 0 ? "parent" : "child");
$html = '';
if (isset($category['contentChild'][$parent])) {
$html .= '<ul class="im-'.$css_class.'">'."\n";
foreach ($category['contentChild'][$parent] as $cat_id) {
if (!isset($category['contentChild'][$cat_id])) {
$html .= '<li id="'.$css_class.'-'.$cat_id.'">
<a href="" data-cap= "">im child content test---'
. $category['contentCat'][$cat_id]['content'] .
'</a>';
'</li>'."\r";
} else {
$html .= '<li id="'.$css_class.'-'.$cat_id.'">
<a href="" data-cap= "">hello parent test------'
. $category['contentCat'][$cat_id]['content'] .
'</a>'."\r";
$html .= listContentTree($cat_id, $category);
$html .= '</li>'."\r";
}
}
$html .= '</ul>'."\n";
}
return $html;
}
how check to for last child.
if(has last child){
then display content of last child
}else{
//where parent doesnt have any child
display content of parent
}

PHP array with levels to HTML tree

I have an array in php that looks kind of like this:
array[x][0]=item name
array[x][1]=level
so, for example,
array[0][0]="Node 1"
array[0][1]=0
array[1][0]="Node 2"
array[1][1]=0
array[2][0]="Node 2.1"
array[2][1]=1
array[3][0]="Node 2.1.1"
array[3][1]=2
array[4][0]="Node 2.2"
array[4][1]=1
I need to turn it into an html ul list, but one that looks like this:
<ul>
<li>
<input type="checkbox" /><span>Node 1</span>
</li>
<li>
<input type="checkbox" /><span>Node 2</span>
<ul>
<li>
<input type="checkbox" /><span>Node 2.1</span>
<ul>
<li><input type="checkbox"><span>Node 2.1.1</span></li>
</ul>
</li>
<li>
<input type="checkbox" /><span>Node 2.2</span>
</li>
</ul>
</li>
</ul>
The biggest catch is the position of the </li> tag - it needs to be after the next <ul> tag. So it's <li> current node <ul><li> child node </li></ul></li>. It's that last </li> that gets me.
This format is necessary to work with the jquery plugin I'm using (https://github.com/daredevel/jquery-tree).
I've seen the suggestions here: create html list from array with levels but that doesn't work due to the extra .
I think there's a solution to this using recursion and array slicing, but that seems inefficient. So far, my attempts at an iterative solution have failed...
You can use this function to convert your array to a nested HTML list (echo nestedHtmlList($array);)
function nestedHtmlList($array) {
$depth = 0;
$result = "";
foreach ($array as $node) {
$newDepth = $node[1];
if ($newDepth > $depth) {
$result .= "<ul><li>";
} else if ($newDepth < $depth) {
for ($d = $newDepth; $d < $depth; $d++) {
$result .= "</li></ul>";
}
$result .= "</li><li>";
} else if ($result == "") {
$result .= "<ul><li>";
} else {
$result .= "</li><li>";
}
$result .= "<input type='checkbox' /><span>";
$result .= $node[0];
$result .= "</span>";
$depth = $newDepth;
}
while ($depth > 0) {
$result .= "</li></ul>";
$depth -= 1;
}
return $result;
}
Tell me what you think:
Code
$array = [];
$array[0][0]="Node 1";
$array[0][1]=0;
$array[1][0]="Node 2";
$array[1][1]=0;
$array[2][0]="Node 2.1";
$array[2][1]=1;
$array[3][0]="Node 2.1.1";
$array[3][1]=2;
$array[4][0]="Node 2.2";
$array[4][1]=1;
function makeList( &$array, $level = null ) {
$html = '<ul>';
$html .= '<li>Level: ' . $level;
while( $element = array_shift( $array ) ) {
if( $level == $element[1] ) {
$html .= '</li><li><label><input type="checkbox"/> ' . $element[0] . '</label>';
} else if( $level < $element[1] ) {
array_unshift( $array, $element );
$html .= makeList( $array, $element[1] ) . '</li>';
} else {
array_unshift( $array, $element );
break;
}
}
$html .= '</ul>';
return $html;
}
echo '<pre>';
echo makeList($array);
Output (human rendered html :D)
Level:
[] Node 1
[] Node 2
Level: 1
[] Node 2.1
Level: 2
[] Node 2.1.1
[] Node 2.2

Magento diplaying category tree dynamically

I need to display my category tree as a list in a responsive menu.
The idea is to display the highest level categories. and create dynamically a list that will be displayed for each category that has children.
I stumbled upon a code that helped me a bit, but i can't figure how to get the job done.
Here is the code:
<?php
$rootCatId = Mage::app()->getStore()->getRootCategoryId();
function getTreeCategories($parentId, $isChild){
$allCats = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('is_active','1')
->addAttributeToFilter('include_in_menu','1')
->addAttributeToFilter('parent_id',array('eq' => $parentId));
$class = ($isChild) ? "sub-cat-list" : "cat-list";
$html .= '<ul class="'.$class.'">';
$children = Mage::getModel('catalog/category')->getCategories(7);
foreach ($children as $category) {
{
$html .= '<li>'.$category->getName()."";
$subcats = $category->getChildren();
if($subcats != ''){
$html .= getTreeCategories($category->getId(), true);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
$catlistHtml = getTreeCategories($rootCatId, false);
echo $catlistHtml;
?>
Thank you in advance.
you can use this to create category tree:
<?php
$rootCatId= Mage::app()->getStore()->getRootCategoryId();
$categories = Mage::getModel('catalog/category')->getCategories($rootCatId);
$output= '<ul>';
foreach($categories as $category) {
$cat = Mage::getModel('catalog/category')->load($category->getId());
$count = $cat->getProductCount();
$output .= '<li>' . '' . $category->getName() . "";
if ($category->hasChildren()) {
$children = Mage::getModel('catalog/category')->getCategories($category->getId());
$array .= get_categories($children);
}
$output .= '</li>';
}
echo $output . '</ul>';
?>
For the effects of showing / hiding categories and subcategories, you can use plain css or jQuery / Prototype.

Change PHP code to MVC Codeigniter

I've made a recursive function to display the menu as a tree (each domain to have sub domains, and so on). The code works as is with a database, but I want to make it MVC to include it into my Codeigniter project.
I've tried splitting everything related to the database into the model, and so on... but doesn't work. You can see below the raw code, maybe someone can guide me how to change it to the MVC model. Thanks!!
<?php
$result = mysql_query("select id_domeniu, nume_domeniu, parent from domenii");
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
while ($row = mysql_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a>";
$html .= buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
?>
<!doctype html>
<html lang=''>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="script.js"></script>
<title>Test</title>
</head>
<body>
<div id='cssmenu'>
<?php echo buildMenu(0, $menu);; ?>
</div>
</body>
<html>
My attempt:
Model:
<?php
class New_menu_model extends CI_Model {
function get_domains() {
$result = $this->db->get ( 'domenii' );
return $result;
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
while ($row = mysql_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
}
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a>";
$html .= buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
}
?>
Controller:
function afisare_domenii_tree() {
$this->load->model ( 'new_menu_model' );
$data['domains'] = $this->new_menu_model->buildMenu ();
$this->load->view('new_menu', $data);
}
View (using a bootstrap template):
<?php echo buildMenu(0, $menu);?>
function get_domains() {
$result = $this->db->get ( 'domenii' );
return $result;
You already returned from the function above, the code after it will not execute. This should have been more like
function get_domains() {
$result = $this->db->get ( 'domenii' );
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
while ($row = mysql_fetch_assoc($result)) {
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
return $menu;
}
I have updated your model. You cannot use mysql_ functions - Instead take a look at Codeigniter's Query Builder functions here ... http://www.codeigniter.com/userguide3/database/query_builder.html
<?php
class New_menu_model extends CI_Model {
function get_domains() {
$result = $this->db->get ( 'domenii' );
$menu = array(
'menus' => array(),
'parent_menus' => array()
);
foreach($result->result_array() as $row)
{
//creates entry into menus array with current menu id ie. $menus['menus'][1]
$menu['menus'][$row['id_domeniu']] = $row;
//creates entry into parent_menus array. parent_menus array contains a list of all menus with children
$menu['parent_menus'][$row['parent']][] = $row['id_domeniu'];
}
return $menu;
}
function buildMenu($parent, $menu) {
$html = "";
if (isset($menu['parent_menus'][$parent])) {
$html .= "<ul>";
foreach ($menu['parent_menus'][$parent] as $menu_id) {
if (!isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a></li>";
}
if (isset($menu['parent_menus'][$menu_id])) {
$html .= "<li><a href='#'>" . $menu['menus'][$menu_id]['nume_domeniu'] . "</a>";
$html .= $this->buildMenu($menu_id, $menu);
$html .= "</li>";
}
}
$html .= "</ul>";
}
return $html;
}
}
?>

Better dynamic navigation menu

I have this approach for now:
ctop = $cnew = $cmine = '';
if($actual == 'top') $ctop = 'class="active"';
if($actual == 'last') $new = 'class="active"';
if($actual == 'mine') $cmine = 'class="active"';
$html = '<aside class="panel_derecho">
<div class="tabs"><h4>$donde</h4>
<ul>';
$js = "refrescar_submenu('last_$donde')";
$js_t = "refrescar_submenu('top_$donde')";
$js_r = "refrescar_submenu('mine_$donde')";
$html .= '<li '.$ctop.'>top</li>';
$html .= '<li '.$cnew.'>ultimos</li>';
$html .= '<li '.$mine.'>like</li>';
$html .= ' </ul>
</aside>';
return $html;
wich works as expected:
It generates a list with the desired copy, the desired javascript function parameter, and the active class (for the wanted one)
But i feel it could be less repetitive; and i can already see that it will be expensive to add/edit/remove copys, params, elements, etc.. i just don't know where to beggin..
In case it helps:
$donde represents the type of data (articles, songs, videos, ..)
$actual represents one atribute (new articles, top articles,
articles i like)
// Menu: link => text
$menu = array(
"top" => "top",
"last" => "ultimos",
"mine" => "like"
);
$html = '<aside class="panel_derecho">
<div class="tabs"><h4>$donde</h4>
<ul>';
foreach ($menu as $link => $text)
{
$html .= '<li '.( $link==$actual ? 'class="active"' : '').'>'.$text.'</li>';
}
$html .= ' </ul>
</aside>';
return $html;
$attributes = array("top" => "top", "last" => "ultimos", "mine" => "like");
$html = "<aside class=\"panel_derecho\">
<div class=\"tabs\"><h4>{$donde}</h4>
<ul>";
foreach ($attributes as $key=>$value)
$html .= " <li ". ($actual == $key ? "class=\"active\"" : "") .">{$value}</li>";
$html .= " </ul>
</div>
</aside>";
return $html;

Categories