Reputation: 597
I'm trying to create a function for a hierarchical navigational menu bar.
I want to be able to have something like this...
<ul id="navigation">
<li><a href="#">Menu Item 1</a></li>
<li><a href="#">Menu Item 2</a></li>
<ul>
<li><a href="#">Sub Menu Item 1</a></li>
<li><a href="#">Sub Menu Item 1</a></li>
</ul>
<li><a href="#">Menu Item 3</a></li>
<li><a href="#">Menu Item 4</a></li>
</ul>
I'm using this function, but it's not working properly like I'd like it to. It's showing the main parent links, but not the child links.
function build_navbar($pid,$sub=0)
{
global $db;
$query = $db->simple_select("navbar", "*", "pid='".$pid."'", array("order_by" => "disporder"));
$menu_build = "<ul id=\"navigation\">\n";
while($menu = $db->fetch_array($query))
{
if($sub == 1)
{
$menu_build .= "<ul>\n";
$menu_build .= "<li><a href=\"#\">".$menu['title']."</a></li>\n";
$menu_build .= "</ul>\n";
}
else
{
$menu_build .= "<li><a href=\"#\">".$menu['title']."</a></li>\n";
}
build_navbar($menu['id'],1);
}
$menu_build .= "</ul>\n";
return $menu_build;
}
Perhaps someone can help me fix this? Thanks.
--- New Update ---
Andy Groff, this is what your code is outputting:
<ul id="navigation">
<li><a href="#">Home</a></li>
<ul>
<li><a href="#">Child Link</a></li>
<li><a href="#">Child 2</a></li>
</ul>
<li><a href="#">Parent</a></li>
</ul>
However, I need it modified so it'll output like this:
<ul id="navigation">
<li><a href="#">Home</a>
<ul>
<li><a href="#">Child Link</a></li>
<li><a href="#">Child 2</a></li>
</ul>
</li>
<li><a href="#">Parent</a></li>
</ul>
This is what it is outputting now, Andy:
<ul id="navigation">
</li>
<li><a href="#">Home</a>
</li>
<ul>
<li>
<a href="#">Child Link</a>
</li>
<li><a href="#">Child 2</a>
</ul>
</li>
<li><a href="#">Parent</a>
</ul>
Upvotes: 0
Views: 7004
Reputation: 2670
I think your problem could have something to do with the fact that your function is recursive, but the string you're building gets reset at the top of your function each time, instead of being passed into the function again. Also, I don't see anywhere that sub will get set back to zero for your final iteration. Additionally, it seems like you shouldn't need to query for each individual row. It would be more effective to query once and build the whole menu. I think the recursion can be ditched. Also, I would recommend storing a "sub" flag in your data, instead of using some hard to understand php logic as to whether or not a given row is a sub menu. I made modifications based of these concepts, no idea if it works or not though since I don't have/want to create the data to test it:
function build_navbar()
{
global $db;
//first things first, i'd recommend putting a "sub" flag in your database. This example will use it.
//start off by getting all of the rows. No need for recursion.
$query = $db->simple_select("navbar", "*", "1", array("order_by" => "disporder"));
$menu_build = "<ul id=\"navigation\">\n";
//keep track of what level we're at
$level = 1;
while($menu = $db->fetch_array($query))
{
//get sub from data
$sub = $menu['sub']
//we need to go back to root level
if($sub == 0 && $level == 2){
$level--;
$menu_build .= "</ul></li>\n";
}
else $menu_build .= "</li>\n";
//we need to go up one level
if($sub == 1 && $level == 1)
{
$level++;
$menu_build .= "<ul><li>\n";
}
else $menu_build .= "<li>";
//always print out a link
$menu_build .= "<a href=\"#\">".$menu['title']."</a>\n";
}
$menu_build .= "</ul>\n";
return $menu_build;
}
Upvotes: 1
Reputation: 4215
UPDATE:
Try this:
function build_navbar($pid, $sub=0)
{
global $db;
$class = $sub ? "sub" : "navigation";
$menu_build = "<ul class=\"$class\">\n";
$query = $db->simple_select("navbar", "*", "pid='".$pid."'");
while($menu = $db->fetch_array($query))
{
$menu_build .= "<li><a href=\"#\">".$menu['title']."</a>\n";
// build child links
$menu_build .= build_navbar($menu['id'],1);
}
$menu_build .= "</ul>";
return $menu_build;
}
What we are doing here, is allowing each function to build a <ul><li>
group, the $sub
variable will determine what the ID of the <ul>
will be, allowing you to theme each ul differently.
EDIT:
I found it!
this line
build_navbar($menu['id'],1);
needs to be changed to this:
$menu_build = build_navbar($menu['id'],1);
It looks like it should work to me.
What I would do is add some echo
statements displaying the SQL query that is being executed each time, then you can copy that into phpmyadmin (or what ever db browser you use). See if it also returns a null result. If it does, there might be something wrong with your data as well.
so for example:
echo "SELECT FROM navbar * WHERE pid='$pid' ORDER_BY disporder;<br>";
Upvotes: 0