2

I want to built a database driven multilevel menu I got it from [http://abhijitpal.in/][1] but the problem here is i can't put class = "dropdown" only to the top menus <ul>, it also get applies to the sub menus as well. I just modified a little but I don't know how to use recursive function. Below is the code, please see if you can help

<?php     /** Function to display Catelogue Menu */

//select all rows from the main_menu table
$q ="SELECT * FROM catelogue WHERE cat_visibility = '1'";    
$r = mysqli_query($dbc, $q);

//create a multidimensional array to hold a list of menu and parent menu
$menu = array(
    'menus' => array(),
    'parent_menus' => array()
);

//build the array lists with data from the menu table
while ($row = mysqli_fetch_assoc($r)) {
    //creates entry into menus array with current menu id ie. $menus['menus'][1]
    $menu['menus'][$row['cat_id']] = $row;
    //creates entry into parent_menus array. parent_menus array contains a list of all menus with children
    $menu['parent_menus'][$row['cat_parentid']][] = $row['cat_id'];
}

    // Create the main function to build milti-level menu. It is a recursive function.  
    function nav_catelogue($parent, $menu) {
    //$html = "";
    if (isset($menu['parent_menus'][$parent])) { ?>
<ul>
        <?php
        foreach ($menu['parent_menus'][$parent] as $menu_id) {
            if (!isset($menu['parent_menus'][$menu_id])) { ?>
                <li><a href="<?php echo $menu['menus'][$menu_id]['link']; ?>"><?php echo $menu['menus'][$menu_id]['cat_name']; ?></a></li>
  <?php }
            if (isset($menu['parent_menus'][$menu_id])) { ?>
        <li><a href="#"><?php echo $menu['menus'][$menu_id]['cat_name']; ?></a>
                        <?php echo nav_catelogue($menu_id, $menu); ?>
                    </li>
            <?php }
        } ?>
     </ul>
<?php }

} 
?>

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:

  • HOME
  • ABOUT
    • History
    • Services
  • Contact

This is the final code as per @Mave

<?php     /** Function to display Catelogue Menu */

//select all rows from the main_menu table
$q ="SELECT * FROM catelogue WHERE cat_visibility = '1'";    
$r = mysqli_query($dbc, $q);

//create a multidimensional array to hold a list of menu and parent menu
$menu = array(
    'menus' => array(),
    'parent_menus' => array()
);

//build the array lists with data from the menu table
while ($row = mysqli_fetch_assoc($r)) {
    //creates entry into menus array with current menu id ie. $menus['menus'][1]
    $menu['menus'][$row['cat_id']] = $row;
    //creates entry into parent_menus array. parent_menus array contains a list of all menus with children
    $menu['parent_menus'][$row['cat_parentid']][] = $row['cat_id'];
}

    // Create the main function to build milti-level menu. It is a recursive function.  
    function nav_catelogue($parent, $menu, $top = false) {
        if (isset($menu['parent_menus'][$parent])) {
            //this is short code for if($top === true) { //do true } else { //do false }
            echo $top ? '<ul class="dropdown">' : '<ul>';
            foreach ($menu['parent_menus'][$parent] as $menu_id) {
                if (!isset($menu['parent_menus'][$menu_id])) {
                    echo '<li><a href="' . $menu['menus'][$menu_id]['link'] . '">' . $menu['menus'][$menu_id]['cat_name'] . '</a></li>';
                }
                if (isset($menu['parent_menus'][$menu_id])) {
                    echo '<li><a href="#">' . $menu['menus'][$menu_id]['cat_name'] . '</a>' . nav_catelogue($menu_id, $menu) . '</li>';
                }
            }
            echo '</ul>';
        }
    }
?>

2 Answers 2

1
function nav_catelogue($parent, $menu, $top = false) {
    if (isset($menu['parent_menus'][$parent])) {
        //this is short code for if($top === true) { //do true } else { //do false }
        echo $top ? '<ul class="dropdown">' : '<ul>';
        foreach ($menu['parent_menus'][$parent] as $menu_id) {
            if (!isset($menu['parent_menus'][$menu_id])) {
                echo '<li><a href="' . $menu['menus'][$menu_id]['link'] . '">' . $menu['menus'][$menu_id]['cat_name'] . '</a></li>';
            }
            if (isset($menu['parent_menus'][$menu_id])) {
                echo '<li><a href="#">' . $menu['menus'][$menu_id]['cat_name'] . '</a>' . nav_catelogue($menu_id, $menu) . '</li>';
            }
        }
        echo '</ul>';
    }
}

When you first call nav_catelogue (not present in your current code), call it with nav_catelogue($menu_id, $menu, true);

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot for the answer.... but can you explain, that first you made ` $top=false ` and asked to set it true on first call. what it will do. jst for my knowledge
this is what the output I am getting <ul class=dropdown"><ul><li>Hisory</li><li>Services</li></ul> there is no list item in the first <ul> . And this is not activating the javascript applied to the class. Please help
The $top = false means that, if you do not give a third variable to the function, it will default to false. Only in one case do you want it to be true: when it's first called. As for no output: I don't know. My code should match your code as you posted it.
ok I am re posting the code with your new code. Please match it up with your code
0

You have two ways to make your recursive function put the

class="dropdown"

The first way is to go for a calling/callee style in which your calling function will treat the first case(class="dropdown") and then call the recursive function which will handle the general case(no class="dropdown").

Add an argument(boolean ?) that you'll transmit at first call and which will add the class="dropdown". On the recursive calls you'll transmit this boolean as false(no class="dropdown" insertion).

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.