tags:

views:

44

answers:

1

Hi all,

I am trying to display a recursive list in PHP for a site I am working on.

I am really having trouble trying to get the second level to display. I have a function that displays the contents to the page as follows.

   function get_menu_entries($content,$which=0)
{
    global $tbl_prefix, $sys_explorer_vars, $sys_config_vars;

    // INIT LIBRARIES
    $db = new DB_Tpl();
    $curr_time = time();
    $db->query("SELECT * FROM ".$tbl_prefix."sys_explorer WHERE preid = '".$which."' && config_id = '".$sys_explorer_vars['config_id']."' && blocked = '0' && startdate < '".$curr_time."' && (enddate > '".$curr_time."' || enddate = '') ORDER BY preid,sorting");

    while($db->next_record()){
        $indent = $db->f("level") * 10 - 10;

        $sitemap_vars['break'] = "";
        $sitemap_vars['bold'] = "";

        if($db->f("level") == 2) {
            $sitemap_vars['ul_start'] = "";
            $sitemap_vars['bold'] = "class='bold'";
            $sitemap_vars['ul_end'] = "";
        }

        switch($db->f("link_type"))
        {
            case '1': // External Url
                $sitemap_vars['hyperlink'] = $db->f("link_url");
                $sitemap_vars['target'] = "";
                if($db->f("link_target") != "") {
                    $sitemap_vars['target'] = "target=\"".$db->f("link_target")."\"";
                }
            break;

            case '2': // Shortcut
                $sitemap_vars['hyperlink'] = create_url($db->f("link_eid"),$db->f("name"),$sys_config_vars['mod_rewrite']);
                $sitemap_vars['target'] = "";
            break;

            default:
                $sitemap_vars['hyperlink'] = create_url($db->f("eid"),$db->f("name"),$sys_config_vars['mod_rewrite']);
                $sitemap_vars['target'] = "";
            break;
        }

        if($db->f("level") > 1) {
            $content .= "<div style=\"text-indent: ".$indent."px;\" ".$sitemap_vars['bold']."><a href=\"".$sitemap_vars['hyperlink']."\" ".$sitemap_vars['target'].">".$db->f("name")."</a></div>\n";
        }

        $content = get_menu_entries($content,$db->f("eid"));
    }
    return(''.$content.'');
}

At the moment the content displays properly, however I want to turn this function into a DHTML dropdown menu. At present what happens with the level 2 elements is that using CSS the contents are indented using CSS. What I need to happen is to place the UL tag at the beginning and /UL tag at the end of the level 2 elements.

I hope this makes sense. Any help would be greatly appreciated.

A: 

Instead of using <div> tags with indentation, use an unordered list for each level, including the first one. Have your function output <ul> at the start and </ul> at the end, and change <div style="text-indent: ..."> to a simple <li>. Give the first level an ID so you can hook onto it. Then you can use CSS to remove bullet points and change the indentation, etc. You don't need to calculate the indentation or whether to bold the text in PHP—instead, use selectors and allow the browser to figure it out:

ul#menu { margin: 0; padding: 0; }
    ul#menu > li { margin: 0; padding: 0; }
        ul#menu > li > ul { margin-left: 10px; font-weight: bold; }

All this will allow you to use one standard algorithm for generating your list, instead of branching based on the level, as well as making the menu look like a menu to web crawlers, search engines and those with CSS-less browsers.

By the way, you should really be htmlspecialchars-ing all that dynamic text. You don't want a stray < to mess up your markup.

Samir Talwar
Hi Samir, Thanks for you help. My trouble is that I am not sure whare exactly to insert the UL and /UL tags. I have tried experimenting however it keeps displaying multiple UL tags for each level 2 element.
Jason
@Jason: The opening tag should be appended to `$content` just before your big `while` loop, and the closing tag should go right after it.
Samir Talwar