Accessibility Links

Search Blink-Design

Creating your own toolbox menu with jQuery

If you’ve spent a few moments browsing my site then hopefully you had a little play with the toolbox over on the right there. It’s a common feature where you click a new item and the old one shuts before revealing the newly clicked content and whilst there are plenty of plugins available to achieve this, I didn’t like being bound by their rules so I wrote my own script and it’s actually dead easy.

The problem I found with grabbing a jQuery plugin to achieve the effect was that I was forced to use certain markup or it didn’t work. Now I’m a bit picky with my markup and I use whichever suits the content and not the plugin, so I decided to figure my own one out.

Like any good web developer we need to settle down and create a solid base of HTML to build upon. I opted for the unsung hero of markup, the definition list.

It’s used to group a title and a description but is flexible enough to allow multiple titles and multiple descriptions. Not only does it make semantic sense but it also gives you an easy way to hook onto elements with your CSS and jQuery. You should really read up on them if you’re a bit baffled.

So anyway, it would look a little like this:


<dl id="list">
	<dt>Apples</dt>
		<dd>I love apples because they're a taste sensation in my mouth</dd>
	<dt>Pears</dt>
		<dd>Not such a fan of pears because their shape reminds me of bad times in my childhood</dd>	
</dl>

With my list in place I would obviously go ahead and chuck in some CSS to make it look nice. Using my toolbox as the example you can see I made the <dt> quite large and bold and displayed the <dd> in a box beneath it. Great so far.

So at this stage your content is semantically structured and looking joyous which is important because without Javascript enabled this is how users will see it and baby Jeebus will love you forever if your content degrades gracefully.

In the example of the toolbox we want to hide our descriptions and only show them when clicked so we’ll get started with jQuery by hiding the definition descriptions as soon as possible.


$('#list dd').hide();

This basically adds an inline style of display: none; to the descriptions which is fine and now they’re hidden on page load.

We’re now going to break out the function that will do the work for us, and I’ll run through what is happening.


$('#list dt').click(function() {
	var toolboxdt = $(this);
	if (toolboxdt.next('dd').css('display') == 'none') {
	      toolboxdt.next().slideDown('fast');
	      toolboxdt.next().siblings('dd').slideUp('fast');
	} else {
	      toolboxdt.siblings('dd').slideUp('fast');
	}	
});

Allow me to summarise the job of this function.

When a user clicks on a title I want to check if the <dd> adjacent to it is visible, if it isn’t visible then I want it to slide down and I want any other <dd> elements that are open to slide up at the same time. However if the <dd> adjacent to it isn’t hidden (i.e it’s already been opened) then I just want it to shut.

So to kick it off:


$('#list dt').click(function() {

We're saying here "Go to the definition titles inside #list, and if one of them is clicked do the following things inside the function". Easy so far


var toolboxdt = $(this);

On this line we’re saying “Assign the selector $(this) to be the variable toolboxdt”

If you’re not familiar with Javascript then you may be wondering what $(this) is. It basically refers to the actual item that the event is happening on. So if the user clicks on the second definition title in a list of eight, then $(this) will refer to that second one he just clicked on. And because we want to base a lot of our actions on when the user clicked we assign it to a variable called toolboxdt, because using $(this) too frequently can be an inefficient use of resources.

You probably would never see the difference here but it’s good programming practice all the same.


if (toolboxdt.next('dd').css('display') == 'none') {

Basically I'm asking "If the very next sibling to the definition title has got a CSS style attribute of display: none; then do the next block of code, otherwise if it's not true run the else statement" If you remember at the start we hid all the <dd> elements with jQuery so we can be safe in the knowledge that they will all have this display: none; setting to begin with .


toolboxdt.next().slideDown('fast');

So if the <dd> is indeed hidden, we wish to reveal it. The 4th line in English is “Go to the next sibling of the element that was just clicked (the <dt>) and then slide it down”. At this point jQuery will reveal the element using it’s inbuilt slideDown() function and will leave the <dd> set as display: block; once it’s done.

Next we want to hide any boxes that were already open, so we’ll use a similar line of code:


toolboxdt.next().siblings('dd').slideUp('fast');

Once again “Go to the next sibling of the element that was just clicked and then from there find all other siblings that are specifically <dd> and slide them up”.

If a user clicks a definition title the description will slide down, and if they click a different one the previous description will slide up and the new one will reveal itself. Here we need to handle what happens if the user clicks the open one again. If they do we must remember the style setting is now set as display: block; so the if statement is no longer true. We can safely run a line of code in the else statement to hide any open descriptions if the <dt> is clicked again.


	} else {
	      toolboxdt.siblings('dd').slideUp('fast');
	}	
});

By now the code should be making sense to you and should be able to tell what is happening above.

Taking care to add all the necessary brackets we now have a sweet little function that you can customise to work with any kind of markup situation. Isn’t jQuery awesome?

Links

Main Site - http://jquery.com
Documentation - http://docs.jquery.com/Main_Page

Posted on Thursday, April 16th 2009 and there are 13 comments

Categories: HTML, jQuery, Tricks n Tips

13 Comments

Contribute

Fields marked with * are required. Your email will not be shown.

  • Please enter the word you see in the image below: