Help creating Dynamic Navigation with Sub Menu's

Discussion in 'Web Design and Development' started by TheCoupe, Apr 26, 2009.

  1. TheCoupe macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #1
    Hi, I am in a pickle over how to do this.

    I am trying to create 2 menu's for a customers site (1 vert, 1 horiz) both of which can be altered from an admin section to add new categories or sub menu's.

    First question is, would I be best setting up a single MySQL table as:
    menu_id - Primary Key auto increment
    menu_name - Displaying menu title
    menu_link - link to page
    menu_sub_id - Foreign key linked back to menu_id

    or 2 seperate Tables using a foreign key to connect them.

    Second question is, how can I display these. I've been trying all sorts of methods, such as:
    Code:
    <ul>
    <?php do { ?>
         <li><a href="<?php echo $row_Top_Menu['menu_link']; ?>"><?php echo $row_Top_Menu['menu_name']; ?></a>
    <?php } while ($row_Top_Menu = mysql_fetch_assoc($Top_Menu)); ?></li>
    </ul>
    which will display the main menu perfectly fine.

    But I can't for the love of god get the submenu's to display. I've been trying a 'foreach' statement, but I'm relatively new to that, and just can't figure out what I'm doing wrong. This is what I've been trying:
    Code:
    <ul>
    <?php do { ?>
         <li><a href="<?php echo $row_Top_Menu['menu_link']; ?>"><?php echo $row_Top_Menu['menu_name']; ?></a>
              <ul>
                   <?php
                    foreach ($row_Top_Menu['menu_id'] AS $subs) {
                    mysql_select_db($database_gce_db, $gce_db);
                    $query_Top_Sub_Menu = "SELECT * FROM cgc_menu WHERE menu_position = 1 AND menu_parent_id = $subs";
                    $Top_Sub_Menu = mysql_query($query_Top_Sub_Menu, $gce_db) or die(mysql_error());
                    $row_Top_Sub_Menu = mysql_fetch_assoc($Top_Sub_Menu);
                    $totalRows_Top_Sub_Menu = mysql_num_rows($Top_Sub_Menu);
                    echo "<li>".$row_Top_Sub_Menu['menu_name']."</li>";
                   }
                   ?>
              </ul>
         </li>
    <?php } while ($row_Top_Menu = mysql_fetch_assoc($Top_Menu)); ?>
    </ul>
    The verticle menu also has to go 2 levels deep, ie:
    Title1
    ->Submenu1
    ->Submenua
    ->Submenu2
    ->Submenub
    Title2 etc

    Any help on this would be greatly appreciated, not sure if it's just tiredness that's not letting me see the light on this one, but I'm determined to crack this before going any further with the site development.

    Thanks in advance :)
     
  2. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #2
    I'm not sure how all of your code is setup, but here's something to look through. It won't work as is, but my main goal was to show a logical work through.
    PHP:
    <ul>
    <?php
    // Assuming main menu items have a null menu_sub_id
    $query 'SELECT * FROM cgc_menu WHERE menu_sub_id = NULL;';
    $topMenuItems mysql_query($query);

    // Loop through each top menu item
    while ($topItem mysql_fetch_assoc($topMenuItems)) {
      echo 
    "<li><a href='{$topItem['menu_link']}'>{$topItem['menu_name']}</a>";
      
      
    $querySubMenu "SELECT * FROM cgc_menu WHERE menu_sub_id = {$topItem['menu_id']};";
      
    $subMenuItems mysql_query($querySubMenu);
      
      
    $num mysql_num_rows($subMenuItems);
      if (
    $num 0) {
        echo 
    '<ul>';
        
    // Iterate through each sub menu item for this menu
        
    while ($subItem mysql_fetch_assoc($subMenuItems)) {
          echo 
    "<li><a href='{$subItem['menu_link']}'>{$subItem['menu_name']}</a></li>";
        }
        echo 
    '</ul>';
      }
      echo
    "</li>";
    }
    ?>
    </ul>
     
  3. TheCoupe thread starter macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #3
    Thank You !!!

    AngelWatt, you are a genius.

    Made a few alterations to fields being pulled in from the database and everything worked like a charm.

    Can't thank you enough.
     
  4. SrWebDeveloper macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #4
    Might also consider adding in sort order fields so both your top level and sub menus will display as the user wants. In your CMS create an interface that allows left/right and up/down repositioning of menu buttons, which actually simply changes the sort order fields in the table. Then you adjust your queries to sort by those fields ascending.

    -jim
     
  5. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #5
    Cool. I was a little surprised it was on target, but cool. Glad you managed it. A quick note though, this will only work for menus that are 2-deep. If any of your sub-menus take on a sub-menu of their own the code will have to be reworked and potentially some mods to your database in order to be able to recognize depth level.
     
  6. TheCoupe thread starter macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #6
    One more thing...

    I originally had a class for my vert menu .first so that the first <ul> displayed didn't show a top border. How can I re-implement that info this code?

    I'm trying this:
    Code:
    <div id="submenu" class="roundall">
      <ul id="menu">
       <?php 
       // Assuming main menu items have a null menu_sub_id 
         $query_vert = 'SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_parent_id IS NULL;'; 
         $sideMenuItems = mysql_query($query_vert); 
    
       // Loop through each top menu item 
         while ($sideItem = mysql_fetch_assoc($sideMenuItems)) { 
           if ($sideItem['menu_id'] == 1) { 
              echo "<li class="first"><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>";
           }
           else { 
              echo "<li><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>"; 
    			}
    which is just throwing up errors... any suggestions?

    Thanks again
     
  7. TheCoupe thread starter macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #7
    I also managed to tweak the code you gave me to allow for 3 levels deep for my vert menu and tweaked the jquery code for show/hide for the 3 levels.

    It's just been a while since I needed to do much php and it's very easy to forget so all the help and suggestions have been greatly appreciated.
     
  8. angelwatt Moderator emeritus

    angelwatt

    Joined:
    Aug 16, 2005
    Location:
    USA
    #8
    The code part:
    PHP:
    echo "<li class="first">
    Check the quote types (the color coding should be a big clue). Should be single quotes around first. That would be where the error is coming from.

    Also, for this check
    PHP:
    if ($sideItem['menu_id'] == 1) {
    That would only be true for the one menu with that id. I think you want the first sub menu item to to be true here. For that I would recommend creating a counter variable and just increment it in the loop and check that variable instead.
    PHP:
    $i 0;
    while ...
      if (++
    $i == 1) {

    // or, some thing a touch more succinct
    $i=0;
    while ...
      echo 
    "<li", (++$i == ? class='first' ''), "><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>";
    Hope that's clear.
     
  9. TheCoupe thread starter macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #9
    AngelWatt Rules :)

    Hi, sorry for the delay in getting back... and thank you for such fast responses. The code:

    Code:
    $i = 0;
    while ...
      if (++$i == 1) {
    worked like a charm. Can't get over how easy it is to forget some of this stuff when you haven't used it in a while lol.

    Just in case you are interrested... you can have a look at the template I'm building... no links are functional at present. I'm utilizing CSS3 for round corners and drop shadows, which all show up in Safari, Firefox is missing the shadows (but is implemented in the next beta), and everything goes square in IE - cause it blows haha)

    http://cgc.justinarcher.com

    Again, I can't thank you enough for your help :)
     
  10. TheCoupe thread starter macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #10
    Discovered an Error, Need Help

    Hi Guys, thanks for your help before on this, but I've encountered an error once I started to put the proper menu details into the database.

    If I enter the details into the database in the order that they are displayed, ie:
    menu 1
    menu 2
    *submenu1
    **sub-submenu1
    **sub-submenu2
    *submenu2
    **sub-submenu1
    **sub-submenu2
    menu 3
    menu 4

    everything displays perfectly, but if I create all the menu's in a normal fashion in the database:
    menu 1
    menu 2
    menu 3
    menu 4
    *submenu1
    *submenu2
    **sub-submenu1
    **sub-submenu2 etc

    the page starts to display things out of order, placing closing ul tags where they should not be, therefore leaving submenu's as main menu's and sub-submenu's all over the place.

    I hope this makes sence, and hope that someone can point out where my code is going wrong.

    Code:
    <div id="submenu" class="roundall">
            <ul id="menu">
              <?php 
    	// Assuming main menu items have a null menu_sub_id 
    		$query_vert = 'SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_member_only >= 0 AND menu_parent_id IS NULL;'; 
    		$sideMenuItems = mysql_query($query_vert); 
    
    // Loop through each top menu item 
    		$i = 0;
    		while ($sideItem = mysql_fetch_assoc($sideMenuItems)) {  
    		if (++$i == 1) { 
              echo "<li class='first'><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>";
            }
            else { 
              echo "<li><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>"; 
    			}
       
      		$querysideSubMenu = "SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_member_only >= 0 AND menu_parent_id = {$sideItem['menu_id']};"; 
      		$subsideMenuItems = mysql_query($querysideSubMenu); 
       
      		$sidenum = mysql_num_rows($subsideMenuItems); 
      		if ($sidenum > 0) { 
        	echo '<ul>'; 
    
    // Iterate through each sub menu item for this menu 
        	while ($sidesubItem = mysql_fetch_assoc($subsideMenuItems)) { 
          	echo "<li><a href='{$sidesubItem['menu_link']}'>{$sidesubItem['menu_name']}</a>"; 
    		
    		$querysideSubMenu2 = "SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_member_only >= 0 AND menu_parent_id = {$sidesubItem['menu_id']};"; 
      		$subsideMenuItems2 = mysql_query($querysideSubMenu2);
    		
    		$sidenum2 = mysql_num_rows($subsideMenuItems2); 
      		if ($sidenum2 > 0) { 
        	echo '<ul>';
    		
    // Iterate through each sub sub menu item for this menu 
        	while ($sidesubItem2 = mysql_fetch_assoc($subsideMenuItems2)) { 
          	echo "<li><a href='{$sidesubItem2['menu_link']}'>{$sidesubItem2['menu_name']}</a></li>";
    		
        	} 
      echo"</li>";
    		} 
        	echo '</ul>'; 
    		} 
        	echo '</ul>';
      } 
      echo"</li>"; 
    } 
    ?>
            </ul>
          </div>
    Many thanks

    Justin
     
  11. TheCoupe thread starter macrumors member

    Joined:
    Mar 4, 2009
    Location:
    Northern Ireland
    #11
    Resolved :)

    Just in case anyone else should wish to create a similar menu, I am posting the code below. It ended up that I had messed up my closing ul and li tags. So Finally, with a big thank you to Angelwatt for helping me in the beginning, here you go:

    Code:
    <div id="submenu" class="roundall">
      <ul id="menu">
      <?php 
    // Assuming main menu items have a null menu_sub_id 
      $query_vert = 'SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_member_only >= 0 AND menu_parent_id IS NULL;'; 
      $sideMenuItems = mysql_query($query_vert); 
    
    // Loop through each top menu item 
      $i = 0;
      while ($sideItem = mysql_fetch_assoc($sideMenuItems)) {  
      if (++$i == 1) { 
      echo "<li class='first'><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>";
      }
      else { 
      echo "<li><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>"; 
      }
       
      $querysideSubMenu = "SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_member_only >= 0 AND menu_parent_id = {$sideItem['menu_id']};"; 
      $subsideMenuItems = mysql_query($querysideSubMenu); 
       
      $sidenum = mysql_num_rows($subsideMenuItems); 
      if ($sidenum > 0) { 
      echo '<ul>'; 
    
    // Iterate through each sub menu item for this menu 
      while ($sidesubItem = mysql_fetch_assoc($subsideMenuItems)) { 
      echo "<li><a href='{$sidesubItem['menu_link']}'>{$sidesubItem['menu_name']}</a>"; 
    		
      $querysideSubMenu2 = "SELECT * FROM cgc_menu WHERE menu_position = 2 AND menu_member_only >= 0 AND menu_parent_id = {$sidesubItem['menu_id']};"; 
      $subsideMenuItems2 = mysql_query($querysideSubMenu2);
    		
      $sidenum2 = mysql_num_rows($subsideMenuItems2); 
      if ($sidenum2 > 0) { 
      echo '<ul>';
    		
    // Iterate through each sub sub menu item for this menu 
      while ($sidesubItem2 = mysql_fetch_assoc($subsideMenuItems2)) { 
      echo "<li><a href='{$sidesubItem2['menu_link']}'>{$sidesubItem2['menu_name']}</a></li>";
    		
      } 
      echo '</ul>';
      } 
      echo '</li>'; 
      } 
      echo '</ul>';
      } 
      echo"</li>"; 
      } 
    ?>
      </ul>
    </div>
     

Share This Page