A simple jQuery menu with persistence using cookies

Recently I’ve been making a concerted effort to learn jQuery the JavaScript framework as opposed to just using all the wonderful plugins off the shelf.

Recently I needed a bit of code to show and hide a navigation menu, but with persistence using cookies so as you move from page to page it can remember which sections to show. I was pretty confident, using bog standard JavaScript I knew I could knock it out really quickly, but The whole point of learning something new is to learn something new so I decided to do it using jQuery. I was pretty confident, last week I wrote some quite complex form validation code in a fraction of the time I could’ve done it in without using jQuery (it’s that pretty but it works well and it was my first attempt to do anything at all complex).

Getting the menu to work has been quite a struggle and I had to spend a surprising amount of time getting it to work, and judging by the posts on various blogs and groups a lot of other people have been stumped by this one too.

Anyway here is my solution, if anybody can help me simplify it further, their help would be greatly appreciated. Obviously you need to download jQuery, you will need to include the code and you will need an unordered list to act as the menu, in this example id=”#demo-menu”.

A couple of posts have been really invaluable figuring out how to do this, so credit where it’s due, thanks:

View the working example

$(document).ready(function() {

		$("#demo-menu > li > a").not(":first").find("+ ul").slideUp(1);
				
		$("#demo-menu > li > a > span").text('+'); // add an indicator to the menu items to show there is a child menu
		
		$("#demo-menu > li> a").each(function() {
			toggleMenu(this);
			checkCookie(this);
		});



		function checkCookie(id)
			{
				/*
				
						check if there is a cookie set for a sub menu 
						if there is then show the menu
				
				*/
				
				var cookieName = id.id;
				
				var c = readCookie(cookieName);
				
				if(c === 'show') {
					
					$(id).each(function() {
					
						$(this).children("span").text('-');
						$(this).find("+ ul").slideDown('fast');
						
					});
					
				}
			}

		function toggleMenu(id)
			{
				$(id).click(function() {
					/*
							toggle the +/- indicators
					*/
					togglePlusMinus(this);	
					
					/*
						toggle the menu open or closed
					*/
					$(this).find("+ ul").slideToggle("fast");
					
				});
			}
			
		function togglePlusMinus(id)
			{
			
				$(id).each(function() {
				
					if($(this).find("+ ul").is(':visible'))
						{
							$(this).children("span").text('+');
							eraseCookie(this.id);
						}
					else
						{
							$(this).children("span").text('-');
							createCookie(this.id, 'show', 365);
						}
				
				});
			}

});

// cookie functions http://www.quirksmode.org/js/cookies.html

function createCookie(name,value,days)
	{
		if (days)
		{
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	}
function readCookie(name)
	{
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++)
		{
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	}
function eraseCookie(name)
	{
		createCookie(name,"",-1);
	}