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

14 comments

1
NeilJuly 28th 2009 @ 08: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;
    });
  });
}

2
jadwigoJuly 28th 2009 @ 08: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#Methods

that would make the code like:

    $(this).click(function(e) {
      e.preventDefault();
      $("div#togg").toggle(400);
    });

3
SidharthJuly 28th 2009 @ 09:16PM

Curious to know the answer raised by Neil. Why use Drupal.behaviors and not $(document).ready() ?

4
LaurenceJuly 28th 2009 @ 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 :)

5
Drupal Theme GardenJuly 29th 2009 @ 10:54AM

Really nice article. Thanks.

BTW, it's nice to see that you are writing again :-)

6
NeilJuly 30th 2009 @ 08:15PM

Thanks. It's time for me to adjust.

7
Oto ArabaAugust 10th 2009 @ 04:38PM

good stuff, im trying to get the best out of jquery atm. helpful post, thx.

8
silaAugust 18th 2009 @ 06:26PM

Great tip! Thanks a lot,
one question though, i can't manage to make the div invisible as default state. Any clue?

9
cooloAugust 18th 2009 @ 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?

10
LaurenceAugust 19th 2009 @ 02: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.

11
OZzSeptember 14th 2009 @ 09:28AM

I'm also one of the jquery beginners so this tutorial really helped me too .. Thanks!

12
drupal themingOctober 7th 2009 @ 11:35AM

thanks, for this useful information..i am new to drupal and learning from your blogs a lot..

13
mahiNovember 27th 2009 @ 08: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.

14
George2010January 27th 2010 @ 11:01AM

Hi!
I've just a beginner of drupal and I'm starting to absorb all your postings here.
Guys, thanks for sharing. Just keep on posting.

drupal custom development
best drupal developers
drupal agencies

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.

More information about formatting options

14 + 6 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.