I have been messing around with recursion a few hours and just cant get it right!
I want my menu structure to be:
<ul>
<li> menu 1 <ul>
<li> menu 1.1 <ul>
<li> menu 1.1.1 </li>
</ul>
</ul>
<li> menu 2 </li>
<li> menu 3 <ul>
<li> menu 3.1 </li>
</ul>
<li> menu 4 </li>
</ul>
</li>
but i just cant get it right.
print '<ul>';
display_children(0, 0);
function display_children($parent, $level) {
// retrieve all children of $parent
$result = mysql_query('SELECT * FROM kategori WHERE parent="'.$parent.'";');
while ($row = mysql_fetch_array($result)) {
if($row['parent']!=0)
print '<ul>';
print '<li>';
// indent and display the title of this child
echo $row['navn']."
";
// call this function again to display this
// child's children
display_children($row['id'], $level+1);
}
print '</li>';
print '</ul>';
as it is now, it prints the right structure but poops out a crapton of missplaced <ul>
and <il>
my top level menu items have 0 as parent (to indicate that they are the absolut top) and its children have their respective parents id as parent attribut.
i tried to check if the current run through of the function (lets say we were at menu 1.1.1) had parent 0 which, to my surprise, was true as i would have thought the current run through would have have parent "menu 1.1" instead of "menu 1"
Any one able to help me out here? I have been staring at that damn code for waaay to long and if you have a quick fix to how i can get this code snippet to insert UL and IL the right places i would be most grateful!
Thanks in advance, Rasmus
display_children
is perhaps not the best name, something like display_menu_level
might be more descriptive. Think about what it has to do: display a <ul>
, then a number of children, then a </ul>
. Each child is an <li>
, the "navn" text, a submenu, and an </li>
. Just reflect that structure in code, something like this:
function display_menu_level($parent, $level) {
$results = mysql_query('SELECT * FROM kategori WHERE parent="'.$parent.'";');
// Don't print an empty list ("<ul></ul>")
if (mysql_num_rows($results) == 0) return;
// Start the menu
echo '<ul>';
// Display children
while ($row = mysql_fetch_array($result)) {
// Start this child
print '<li>';
// indent and display the title of this child
echo $row['navn']."
";
// call this function again to display this
// child's children
display_children($row['id'], $level+1);
// Close this child
print '</li>';
}
// Close the menu
print '</ul>';
}
Some pseudo-code might put you on the right track:
function display_child_menus(parent_id) {
menus = get_from_db_having_parent(parent_id)
echo UL
foreach (menus as menu) {
echo LI
echo menu->title
children = get_menu_children(id)
if (menu->has_children) {
echo display_child_menus(menu->id)
}
echo /LI
}
echo /UL
}
echo display_child_menus(0)
Notice how it is indented and how much easier to read it is than the code you have posted. This helps a lot in finding what is wrong.
Also notice how I have no mixed database stuff with displaying the data. Make separate functions (here you can see the function get_from_db_having_parent)
You forget to add the opening <li>
tag.
Also, instead of printing directly, store each tag in a an array first.
$parents = array();
While( parent exists )
{
// Query for children again
$children = array();
While(children exist)
{
$children[] = $row2[navn] ;
}
$parents[$row[navn]] = $children;
Unset($children);
}
Now use a foreach to display:
Echo "<ul>";
Foreach ($parents as $k => $v)
{
Echo "<li>".$k;
If (!empty($v))
{
Echo "<ul>";
Foreach($v as $z)
{
Echo "<li>".$z."</li>";
}
Echo "</ul>";
}
Echo "</li>";
}
Echo "</ul>";
I typed on a phone so pardon any errors. I made this a wiki so guys could help edit it. Btw this is untested. But there shouldn't be any bugs.