Coding a Navigation Menu Bar with drop down subpages

Over the past days, I was thinking how to design a navigation menu bar that when you hover it, the sub pages will be shown. I know it’s sounds so easy but the challenging part are these:

  • CSSing the Navigation Bar
  • Designing the Database since will be implementing a sub page that has a sub page and so on and so forth(unlimited SUBs)…
  • Coding the design in PHP and HTML

So then, after days of combat I made my own. Thanks also to my thorough research.

I created 3 files. A class for calling the categories, the HTML and the CSS.

Here’s my Code:

HTML

<?php
     require_once 'categories.php';
     $cat = new Categories();
     $menu = $cat->get_menu();
?>
 <div id="access">
    <div id="nav">
      <div class="menu-header"><?= $menu; ?></div>
     </div>
 </div>

Categories.php (Click here for more info about this class)

<?php
class Categories
{
	var $exclude;
	var $depth;

	function __construct() {
		$this->exclude = array();
		$this->depth = 1;
	}

	function get_menu()
	{
		$nav_query = mysql_query("SELECT * FROM `categories` ORDER BY 'category_id'") or die( mysql_error() );

		$tree = "<ul class='menu'>";					// Clear the directory tree
		$this->depth = 1;					// Child level depth.
		$top_level_on = 1;			// What top-level category are we on?
		array_push($this->exclude, 0);	// Put a starting value in it

		while ( $nav_row = mysql_fetch_array( $nav_query ) )
		{
			$goOn = 1; // Resets variable to allow us to continue building out the tree.
			for( $x = 0; $x < count( $this->exclude ); $x++ )// Check to see if the new item has been used
			{
				if ( $this->exclude[$x] == $nav_row['category_id'] )
				{
					$goOn = 0;
					break; // Stop looking b/c we already found that it's in the exclusion list and we can't continue to process this node
				}
			}
			if ( $goOn == 1 )
			{
				#top category or in other words category who's parent_id is 0
				$tree .= "<li class='menu-item'><a href='#'>".$nav_row['name']."</a>"; // Process the main tree node
				array_push( $this->exclude, $nav_row['category_id'] ); // Add to the exclusion list

				if ( $nav_row['category_id'] < 6 )
				{ $top_level_on = $nav_row['category_id']; }

				$tree .= $this->build_child( $nav_row['category_id'] ); // Start the recursive function of building the child tree
				$tree .= "</li>";
			}
		}

		return $tree."</ul>";
		// echo "</ul>";
	}

	function build_child( $oldID )// Recursive function to get all of the children...unlimited depth
	{
		$child_query = mysql_query( "SELECT * FROM `categories` WHERE parent_id=" . $oldID ) or die( mysql_error() );
		$tempTree .= "<ul class='sub-menu'>";
		while ( $child = mysql_fetch_array( $child_query ) )
		{
			if ( $child['category_id'] != $child['parent_id'] )
			{
				$tempTree .= "<li class='menu-item'><a href='#'>" . $child['name'] . "</a>";
				$this->depth++;		// Incriment depth b/c we're building this child's child tree  (complicated yet???)
				$tempTree .= $this->build_child( $child['category_id'] ); // Add to the temporary local tree
				$this->depth--;		// Decrement depth b/c we're done building the child's child tree.
				array_push( $this->exclude, $child['category_id'] );			// Add the item to the exclusion list
			}
		}
		$tempTree .= "</li></ul>";
		return $tempTree;		// Return the entire child tree
	}

}
?>

CSS

#access {
	display: block;
	float: left;
	height: 31px;
	margin: 0 auto;
	width: 1000px;
}
#access .menu-header, div.menu {
	font-size: 13px;
	margin-left: 12px;
	width: 1000px;
}
#access .menu-header ul, div.menu ul {
	list-style: none outside none;
	margin: 0;
}
#access ul ul {
	box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2);
	display: none;
	float: left;
	left: 0;
	position: absolute;
	top: 38px;
	width: 180px;
	z-index: 99999;
}
#access ul ul ul {
	left: 100%;
	top: 0;
}
#access .menu-header li, div.menu li {
	float: left;
	position: relative;
}
#access ul ul li {
	min-width: 180px;
}
#access li:hover > a, #access ul ul *:hover > a {
	background: none repeat scroll 0 0 #333333;
	color: #FFFFFF;
}

#access ul li:hover > ul{
	display: block;
}
#access ul ul a {
	background: none repeat scroll 0 0 #333333;
	height: auto;
	line-height: 1em;
	padding: 10px;
	width: 160px;
}
#access a {
	display: block;
	line-height: 34px;
	padding: 0 10px;
	text-decoration: none;
}

Now everything is just a piece of cake! Since this code is designed to be dynamic, there’s no worrying how many sub pages you’ll create.
The finish product would look like this:

Just edit the CSS and you’ll be golden!
Hope this help someone! Have a Happy Coding! :)