Creating a Dropdown Menu with jQuery and CSS

The raw base

To start off with, we’re going to at least need some sort of menu structure to get us going. For this, the best way to structure the menu is using an unordered list (ul), nesting your submenus as you go. Below is the example we’re going to use in this demo it its raw unstyled format.

(The running demo is here – http://blog.subooa.com/example/css_jquery_dropdown.html)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<title>Creating a dropdown menu with jQuery and CSS</title>
	</head>
</html>
<div id="mainmenu">
	<ul>
		<li><a href="#">Menu item 1</a>
			<ul>
				<li><a href="#">Submenu item 1</a></li>
				<li><a href="#">Submenu item 1</a></li>
			</ul>
		</li>
		<li><a href="#">Menu item 2</a></li>
		<li><a href="#">Menu item 3</a></li>
		<li><a href="#">Menu item 4</a>
			<ul>
				<li><a href="#">Submenu item 4.1</a></li>
				<li><a href="#">Submenu item 4.2</a></li>
			</ul>
		</li>
		<li><a href="#">Menu item 5</a></li>
	</ul>
</div>
</body>
</html>

Opening that in a browser is going to be pretty plain, something like this:
raw_menu

A little css

For the sake of this tutorial we’re only going to give the menu a basic look and not get too fancy. So we’ll just create a nice green and black menu.

The nav we are going to create is going to be a left to right manu, with the second level popping out below its parent, so we first need to order the items left to right and get the submenu it the right position. (To keep it simple, the style is going to be added to the same file and not extracted into a saperate stylesheet)

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
	<style type="text/css">
 
		body{
			margin: 0px;
			font-family: Arial, Verdana, Helvetica, Sans-Serif;
		}
 
		#mainmenu ul{
			width: 100%;
			height: 30px;
			background-color: #393;
			margin: 0px;
			padding: 0px;
			font-size: 12px;
		}
			#mainmenu ul li{
				float: left;
				list-style: none;
				margin: 0px;
				position: relative;
				height: 30px;
				width: 100px;
			}
				#mainmenu ul li a{
					display: block;
					padding: 0px 10px;
					height: 30px;
					line-height: 30px;
					color: #FFF;
					text-decoration: none;
					border-right: 1px solid #363;
					border-left: 1px solid #3c3;
				}
 
				#mainmenu ul li ul{
					width: 170px;
					position: absolute;
					left: 0px;
					float: left;
					clear: left;
				}
					#mainmenu ul li ul li{
						background-color: #000;
					}
						#mainmenu ul li.hover ul li a{
							border-width: 0px;
							border-bottom: 1px solid #CCC;
							background-color: #000;
							height: 29px;
							width: 150px;
						}	
	</style>

style_no_js

Hiding the submenu

Now that the menu is working and displaying as we want it to, now we need to hide the submenu by default and setup the style for the hover state.

Change the left value for the “#mainmenu ul li ul” class to be off the screen somewhere (we’re using -12000px here) and add a new hover class for the list item, which moves the ul back to where we just had it when the user hovers over the main menu item.

40
41
42
43
44
45
46
47
48
49
50
				#mainmenu ul li ul{
					width: 170px;
					position: absolute;
					left: -12000px;
					float: left;
					clear: left;
				}
 
					#mainmenu ul li.hover ul{
						left: 0px;
					}

Adding the jQuery event… the fun part

Up to this point, the file could run as a standalone HTML file, and with a little extra CSS could actually work in a lot of browsers, but there are many out there that don’t support using the “:hover” on list items, so we need to make use of some javascript to tell the browser to react when the user hovers over the main menu items. So first step here is to actually load the jQuery javascript:

?View Code JAVASCRIPT
63
64
65
66
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></script>
	<script type="text/javascript">
		jQuery.noConflict();
	</script>

(The no conflict line has been added in cases where people may already be calling a javascript file that makes use of $, it prevents us from running into any javascript code conflicts)

And now here is where the magic happens, using jQuery you can ‘chain’ function calls one after the other without having to do each function call on an element on its own line which cuts down the file size and keeps things neat and together.

?View Code JAVASCRIPT
64
65
66
67
68
69
70
71
72
73
74
75
	<script type="text/javascript">
		jQuery.noConflict();
 
		jQuery(document).ready(function(){
			jQuery('#mainmenu').find('li').mouseenter(function(){
				jQuery(this).addClass('hover');
			}).mouseleave(function(){
				jQuery(this).removeClass('hover');
			});
		});
 
	</script>

Finally, just to top things off we need to add some hover colors to the menu items.

63
64
65
66
67
68
69
 
				#mainmenu ul li.hover a{
					background-color: #3c3;
				}
				#mainmenu ul li ul li.hover a{
					background-color: #333;
				}

final_dropdown_menu

And that’s it, a fully functional CSS dropdown using jQuery. In a later article, I’ll cover adding a slight animation and also adding multiple levels of dropdowns.

Demo and full code

Here’s the running demo – http://blog.subooa.com/example/css_jquery_dropdown.html
In case you got a little lost along the way, you can download the full code here to play with – css_jquery_dropdown.zip

Ajax in Joomla with jQuery

This article came about while I was building a custom Joomla component at work, the component required a multi step form that stayed on the same page. So data needed to be grabbed from the database and displayed on the screen as the user was filling in the form.

I wont go into the details of making a custom component as that is outside the scope of this article, more information on that can be found here, instead we’ll just grab an article assuming that it belongs to a menu and has the Itemid of 10 (you can call absolutely any component you like, as long as you know the non SEF link to the page you are after).

First of all we need to load jQuery, we’ll load this from Googles server to reduce the load on our own server

?View Code JAVASCRIPT
1
2
3
4
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
	jQuery.noConflict();
</script>

We’ll also need to setup a new file in the /templates/system/ folder called barebones.php that will be called when we make our Ajax calls instead of the normal template so that the data returned doesn’t include the main template, css, javascript etc. Create the file, and enter in the following:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
/**
 * @copyright	Copyright (C) 2009 subooa.com. All rights reserved.
 * @license	GNU/GPL, see LICENSE.php
 * @author	Chris Duell (subooa.com)
 * barebones is a stripped template by subooa. 
 */
 
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
?>
<jdoc:include type="component" />

Now to making the Ajax call, you will need a place to put the data once it is loaded, so create a div with the id of “ajax_here”.

Using jQuery, the Ajax call is pretty striaght forward:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
jQuery(document).ready(function(){
	jQuery.ajax({
		type: "GET",
		url: "index.php",
		data: "?Itemid=10&tmpl=barebones",
		success: function(html){
			jQuery("#ajax_here").html(html);
		}
	});
});

Quickly stepping through this, we are making a call to index.php and requesting the article associated with Itemid 10, and after the data is received adding it to the div that we created earlier that has the id of “ajax_here”. But most importantly, we explicitly call the “barebones” template so the data returned and entered into the div is ONLY the output for the component, nothing more.

I highly recommend using Firebug as you are developing and testing this so that you can see if the Ajax calls are being correctly made, and the expected results are being returned.

This article is quite basic on purpose, however if you would like more information just leave a comment.

Back to Top