Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

TheCoupe

macrumors member
Original poster
Mar 4, 2009
53
0
Northern Ireland
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 :)
 
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>
 
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.
 
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
 
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.

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.
 
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
 
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.
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.
 
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 == 1 ? class='first' : ''), "><a href='{$sideItem['menu_link']}'>{$sideItem['menu_name']}</a>";
Hope that's clear.
 
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 :)
 
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
 
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>
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.