0

I am trying to design a dynamic vertical menu : my table is:

primary // primary key 
pid  //parent id 0 if none
cid //the actual category id
comment //some comment

the thing is that I want to design a php function where after reading the values from database it should output it into an html ordered list (like a multilevel nested unordered list) I know that it would be easily achieved by using a recursion function the problem is that i just can't do it.. I've tried many times but failed in vain The main problem comes in nesting (where to give list items and where to start the list)

I would be very grateful if anyone of you could help me out...

well i've managed to write an ugly code: {here i ve used two tables one for the parent and one for the child}

$query="SELECT * FROM parentCat";
$result=mysql_query($query);

echo "<ul id=\"suckertree1\">";

while($row=mysql_fetch_array($result))
{
    $name=$row['comment'];
    $pid=$row['catid'];
    echo "<li><a href=\"#\"> $name</a> ";
    $query="select * from childCat WHERE pid=$pid";
    $subresult=mysql_query($query);
    $af=mysql_num_rows($subresult);
    if($af>0)
    {
        echo "<ul>";

        while($subrow=mysql_fetch_array($subresult))
            {
                $name=$subrow['comment'];
                echo "<li><a href=\"#\"> $name</a> </li>";

            }
            echo "</ul>";
    }
    echo "</li>";
}
echo "</ul>";

it will show only one sublevel... wht should i do to make it work for infinite level

1
  • 1
    Start by using a dictionary...Then post the code you tried so far! (even if it looks ugly or bad designed to you) ;) Commented Feb 12, 2011 at 9:54

3 Answers 3

2

I thing a while script is best for you

$query = mysql_query("SELECT * FROM menu ORDER BY primary ASC");
$parent=0;
$sub=0
echo "<ul>";//start list
while($menu = mysql_fetch_array($query){
   if($parent != $menu['pid']){//if not seen item before
      if($sub != 0){echo "</ul>";}else{$sub++;}//if not first submenu, close submenu before. If first sub sub++.
      echo "<ul>";}//open submenu
   echo "<li>".$menu[cid]."</li>";//echo item
   if($parent != $menu['pid']){//if not seen before
      $parent = $menu['pid']; //set to seen before so next loop will be recognised
   }
}
echo "</ul>"; //end list

I dont know if this is gonna work since I did not test it, but it should show you an option on how it could be done. Idea of lists:

<ul>
  <li>Item1</li>
   <ul>
    <li>Subitem1</li>
    <li>Subitem2</li>
   </ul>
  <li>Item 2</li>
   <ul>
    <li>Subitem1 of Item2</li>
   </ul>
</ul>

Gives:

  • Item1
    • Subitem1
    • Subitem2
  • Item2
    • Subitem1 of Item2
Sign up to request clarification or add additional context in comments.

1 Comment

A ul as a child of a ul is not valid. The child ul must be inside a li
0

Try this, it should do the trick.

<?php

$query = "SELECT a.comment parent
               , b.comment child
          FROM menu a
          JOIN menu b
          ON a.primary = b.pid
          ORDER BY a.primary";

$result = mysql_query($query);
$parent = ''; 
echo "<ul>";
foreach ($result as $next) {
   if ($next['parent'] != $parent) {
      if (strlen($parent) > 0) {
         echo "    </ul>";
         echo "  </li>";
      }   
      echo "  <li>" . $next['parent'];
      echo "    <ul>";
   }   
   echo "    <li>" . $next['child'] . "</li>";

   $parent = $next['parent'];
}
echo "    </ul>";
echo "  </li>";
echo "</ul>";

?>

Comments

0

To render a nested list for an assoc array try this:

<?php
$list = array(
    'item-1' => 'test-1',
    'item-2' => 'test-2',
    'item-3' => array(
        'item-3-1' => 'test-3',
        'item-3-2' => array(
            'item-3-2-1' => 'test-4',
            'item-3-2-2' => 'test-5',
        ),
    ),
    'item-4' => 'test-6',
);

function render_list($list) {
    echo '<ul>';
    foreach ($list as $key => $value) {
        echo '<li>';
        echo $key.':';
        if (is_array($value)) render_list($value);
        else echo $value;
        echo '</li>';
    }
    echo '</ul>';
}

render_list($list);

Which will result in this:

<ul>
    <li>item-1:test-1</li>
    <li>item-2:test-2</li>
    <li>
        item-3:
        <ul>
            <li>item-3-1:test-3</li>
            <li>
                item-3-2:
                <ul>
                    <li>item-3-2-1:test-4</li>
                    <li>item-3-2-2:test-5</li>
                </ul>
            </li>
        </ul>
    </li>
    <li>item-4:test-6</li>
</ul>
  • item-1:test-1
  • item-2:test-2
  • item-3:
    • item-3-1:test-3
    • item-3-2:
      • item-3-2-1:test-4
      • item-3-2-2:test-5
  • item-4:test-6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.