AJAX and AHAH for Drupal themers.
Harnessing the Power of Drupal.behaviors and Drupal.attachBehaviors
One of the most frustrating situations I've run into in Drupal has been how to make use of jQuery AJAX/AHAH calls in a theme (will just call it AJAX for simplicity's sake). I say frustrating because we have all the tools we need to accomplish this task out-of-the-box in Drupal. We have jQuery, we can easily add custom .js files in the theme and we have nearly endless control over the display of information that we want to use through templating, CCK, Views, Context, etc.
So, if you're comfortable writing AJAX calls in jQuery (something which they made remarkably simple and is well documented), you of course can just add the js to your script file and poof! ...like magic, you're doing AJAX in Drupal. You feel like a ninja, like anything is possible, until... you don't. Because any HTML you grab from another page that has javascript events attached is suddenly event-less after your AJAX call. For example, you grab a slideshow or even just a link with a click event on it and all of a sudden after your AJAX retrieves that info, the javascript is absent. This may sound like an edge-case, but you'd be amazed how much of the content you want to grab needs these events. If you're like me, you might be thinking at this point: "But I can make those events run regardless of when they are used using the .live event." This is true, but in a CMS-powered site, how many of these calls can you really have that kind of control over? Typically, you're leveraging other modules to create these script-driven areas of your site, e.g., Views Slideshow to create a slideshow. So, just as quickly as you feel powerful, the power seems gone.
Bad turns to worse when you realize there is also very little documentation on drupal.org about this. Most articles there for creating AJAX driven applications are geared toward module developers and in turn can be confusing for front-end developers and just don't speak directly to this task. Thankfully, I was able to extract from this documentation and a couple of helpful blog posts - here and here (and a little trial/error) the very simple solution to this.
Drupal.behaviors and Drupal.attachBehaviors
While the documentation for this might be lacking, the code is very much not. In fact, the jQuery/javascript built into core Drupal (drupal.js) has an incredibly powerful way of dealing with this. So let's get to it.
Basically, for any script that needs to be run following an AJAX event, wrap it in a Drupal.behaviors function.
Drupal.behaviors.[YOURFUNCTIONNAME] = {
attach: function(context) {
}
};
or in Drupal 6:
Drupal.behaviors.[YOURFUNCTIONNAME] = function() {}
This in turn tells Drupal to store this as a behavior that can then be run every time the function Drupal.attachBehaviors is run.
Drupal.attachBehaviors()
Thankfully, most module developers are aware of this and rather than wrapping their functions in the general jQuery function, they wrap them as a behavior. What's awesome is we can use this same code just as easily in the theme layer. Here's a simple example:
Drupal.behaviors.thisIsABehaviorINeedToRunAfterAjaxCall = {
attach: function(context) {
//jQuery/javascript events here.
} };
or in Drupal 6:
Drupal.behaviors.thisIsABehaviorINeedToRunAfterAjaxCall = function()
//jQuery/javascript events here.
}
// Then, once you've made your AJAX call, include this in your callback:
Drupal.attachBehaviors('Whatever element needs to have those scripts reattached');So, instead of wrapping custom jQuery/javascript in your local .js file with a general jQuery function (e.g., beginning with $(function() {...), wrap it as a behavior if you need it after an AJAX call is made. And once your AJAX call is made, simply run Drupal.attachBehaviors on whatever element needs to have these behaviors assigned. Voila!
And now, your ability to run AJAX/AHAH in the theme layer is truly limitless. Try it! It's a wonderful feeling.
Comments
AJAX and AHAH for Drupal themers. | EvanWillhite.com -
Hi there to all, because I am in fact keen of reading this weblog's post to be updated regularly. It carries nice material.
Add new comment