Drupal Theming + jQuery Basics (inc. Drupal Behaviors)
In this tutorial you'll see how to implement a toggling effect using jQuery within your Drupal theme whilst utilising Drupal behaviors.
The finished effect can be seen in this Drupal jQuery demo.
The toggle is achieved via a two-step process:
- Step 1 - add content and markup to a node
- Step 2 - implement jQuery, utilising Drupal behaviors, which will enable the toggling to work
Step 1 - add content and markup to a node
First add the following code to your node body (remembering to set the input format to Full HTML in order to avoid the div tags getting ignored):
<a href="#" id="togg-link">Click this link to toggle the content displayed below</a>
<div id="togg">
This content will be toggled open and closed using jQuery.
Blah, blah, blah.
</div>There are two key elements within the code:
- the element which, when clicked on, will execute the toggle (in this case the link with an id of 'togg-link')
- the element which will be toggled (in this case the div with an id of 'togg')
Step 2 - implement the jQuery, utilising Drupal behaviors, which will enable the toggling to work
In this tutorial, we'll be implementing our jQuery via a new 'script.js' file which will sit in our theme folder.
Drupal 6 helps us greatly when it comes to including jQuery in themes by doing the following:
- automatically finding this new 'script.js' file and including it (source - Structure of the .info file - scripts)
- auto-including the main 'jquery.js' and 'drupal.js' files for us when it recognises that a certain page requires them
meaning that, in short, all we have to do is write the required jQuery code for the toggle in our new 'script.js' file and it'll work!
So, to start, create a new .js file named 'script.js' and save it within your theme's root folder. i.e.:
/sites/all/themes/mytheme/script.js(replace 'mytheme' with your theme's actual name e.g. 'my_great_theme')
Please note: the file will not automatically be found if you place it within a different location (e.g. /sites/all/themes/mytheme/otherfiles/script.js). Furthermore, if you have already declared other .js files via your theme's .info file you will also have to declare this new file.
Then add the following code to the 'script.js' file:
//togg
Drupal.behaviors.togg = function (context) {
$('a#togg-link:not(.togg-processed)', context).addClass('togg-processed').each(function () {
$(this).click(function() {
$("div#togg").toggle(400);
return false;
});
});
};Nice huh! Err...but what the heck does it all mean? Let's break it down:
Drupal.behaviors.togg = function (context) {
};Create a Drupal behavior (which is simply a function), attach it to the 'Drupal.behaviors' object, and pass in the 'context' object.
$('a#togg-link:not(.togg-processed)', context).addClass('togg-processed').each(function () {
});Loop through all instances of 'a#togg-link' which do not already have a class of 'togg-processed', add a class of 'togg-processed' and...
$(this).click(function() {
});...attach a click function, which will execute when '$(this)' (i.e. our link) is clicked.
$("div#togg").toggle(400);When the click function is executed, toggle the div with an id of 'togg' at a speed of 400 milliseconds...
return false;... and prevent the link from working (ordinarily clicking on a link whose destination is a pound sign '#' would jump the user to the top of the page).
Empty cache
If you haven't yet done so empty the cache and enjoy your new Drupal jQuery toggling goodness!
See the section marked 'Empty the cache' in the 'creating custom regions in drupal 6 themes' post for two ways to do so.
Limitations
As stated in the title, this is a basic example. In a more complex scenario where, for example, you wished to apply toggling to multiple items within a node it would be more practical to do so by dynamically assigning ids... although that's a discussion for another post...
Drupal jQuery Book

Drupal 6 JavaScript and jQuery
by Matt Butcher
Useful jQuery Links
jquery.com
visualjquery.com
Working with JavaScript and jQuery



22 comments
@ 8:39pm
How do you feel about this method? I'm not criticizing, I'm just curious on the difference.
Keep the HTML the same
script.js:
if (Drupal.jsEnabled) {$(document).ready(function() {
$('#togg-link').click(function() {
$("#togg").toggle(400);
})
return false;
});
});
}
@ 8:45pm
Nice writeup, wanted to find an easy way for drupal to do stuff like that, but never got around to finding out how to.
One comment though:
event.preventDefault();is the recommended way for jQuery to make links do nothing when you click them: http://docs.jquery.com/Events/jQuery.Event#Methodsthat would make the code like:
$(this).click(function(e) {e.preventDefault();
$("div#togg").toggle(400);
});
@ 9:16pm
Curious to know the answer raised by Neil. Why use Drupal.behaviors and not $(document).ready() ?
@ 10:59pm
Hi all,
thanks for the comments.
@Neil and @Sidharth - I'd suggest the main advantage of using Drupal behaviors is that they are re-attachable, which becomes very useful when utilising AHAH/AJAX. Using '$(document).ready()' within 'script.js' means it will run only once (once the DOM is ready) each page load, whereas behaviors will be attached each time 'Drupal.attachBehaviors()' is called (and in Drupal 6 the 'drupal.js' file (/misc/drupal.js) is already set up to attach all behaviors for us upon intital page load).
Check out the following for further Drupal behaviors discussion:
@jadwigo - interesting - thx, I will check that out :)
@ 10:54am
Really nice article. Thanks.
BTW, it's nice to see that you are writing again :-)
@ 8:15pm
Thanks. It's time for me to adjust.
@ 4:38pm
good stuff, im trying to get the best out of jquery atm. helpful post, thx.
@ 6:26pm
Great tip! Thanks a lot,
one question though, i can't manage to make the div invisible as default state. Any clue?
@ 11:52pm
Thanks for the tips. This got me started. However...
"In a more complex scenario where, for example, you wished to apply toggling to multiple items within a node it would be more practical to do so by dynamically assigning ids... although that's a discussion for another post..."
Any idea of where I could find a resource to help me out with doing what you said in your last paragraph?
@ 2:48pm
@sila - you can hide the #togg div by default using an additional behavior in your 'script.js' file, like so:
Drupal.behaviors.toggdiv = function (context) {$('div#togg:not(.toggdiv-processed)', context).addClass('toggdiv-processed').each(function () {
$(this).hide();
});
};
@coolo - good question! I started writing you an answer and realised that it really does require a full post to cover everything (with examples etc.) - so I will publish that in the near future.
Basically, you can loop through all of your content divs (which contain the content you want to toggle) assigning each an id or class and then loop through all of your toggle links assigning each a corresponding id or class and attaching a click function which will toggle the relevant content when clicked.
It's all done utilising jQuery's each() function and, specifically, using an index (i) - a basic example being:
$(document.body).click(function () {$("div").each(function (i) {
$(this).addClass("example" + i);
});
});
Of course in Drupal we can put the js code inside of a behavior, but I'll add all that in the main post :)
Hope that helps you out for now.
@ 9:28am
I'm also one of the jquery beginners so this tutorial really helped me too .. Thanks!
@ 11:35am
thanks, for this useful information..i am new to drupal and learning from your blogs a lot..
@ 7:29am
great job buddy...
i am a beginner.. and my question is how can i have multiple toggle on the same page??
please help me out.
@ 11:00am
Thanks a lot! Websites with jQuery contribute a lot more professional and look more beautiful. Your introduction has given us great help on.
@ 9:14pm
At first I thought I wasn't going to get much out of this one, but the comments regarding using Drupal.behaviors vs. the standard $(document).ready() approach was very enlightening. Our site uses a fair amount of AJAX and I've found myself having to work around this in other ways.
Very helpful. Thanks!
@ 12:52am
"I'd suggest the main advantage of using Drupal behaviors is that they are re-attachable, which becomes very useful when utilising AHAH/AJAX."
Finally a clear explanation, thank you for a great article. In combination with the following post it's clicked and I have a working dynamic select drilldown;
http://groups.drupal.org/node/20318
:D
@ 7:43pm
Thanks for the great piece of jQuery Laurence, I'm going to try and expand upon it for my next Drupal website.
@ 7:36am
Great tutorial! :)
However, I would love if you added a few lines to this tutorial, describing how to do if you want the togg closed at start and then to push the link to open it.
@ 5:12pm
Great Job Laurence, thank you for this tutorial. Have sought for some time after such a tutorial.
@ 9:38pm
This is the first article and related comments I've found that explains Drupal Behaviors well. Great work.
@ 12:08am
Anyone else having problems with this not working in Safari 5.0 - Windows?
@ 12:10am
Scratch that. It's working now. Don't know why it wasn't....
Comments are closed
If you want to ask a question or have something to add please contact me.