Tags
Are you tired of thinking that how to execute JavaScript behaviors after your AJAX callback in Drupal?
Then, Drupal.behaviors makes it easier than you can think. But first question we found that what is Drupal.behaviors. Lets have a look.
So what’s Drupal.behaviors:
Drupal.behaviors is an object, defined in Drupal Core. It is declared and initialized at the very beginning of JavaScript code in Drupal core along with 4 properties, among which ‘behaviors’ is one of them( like Drupal.settings ). This object contains all the Drupal core properties which can be used and extended by other modules.
Why to use Drupal.behaviors ?
When we started our journey with jQuery, we learnt to put all our code inside the $(document).ready() function as below :
// Get the DOM ready. $(document).ready(function(){ // Do your favi coding here. });
All we know the meaning of the above code. Still let us recall again, it assures us that our code will run after the DOM( Document Object Model ) has been loaded. This only happens once our web page gets refreshed/reloaded. But we want our js code to be executed after our AJAX requests. Will it help us a lot? Obviously NOT! So here, Drupal.behaviors saves us 🙂
How Drupal.behaviors works ?
Drupal.behaviors are generally called after any new DOM element has been added or removed to/from your web page during AJAX requests. Thus it becomes easier to execute your js code. So without wasting any time, lets have look to it’s structure:
For Drupal 6:
Drupal.behaviors.yourModuleName = function(context) {}; // Do your js stuffs you want to do after your AJAX call. }
For Drupal 7:
Drupal.behaviors.yourModuleName = { // This behavior function is called when new element is being added. attach: function (context, settings) { // Do your js stuffs you want to do after your AJAX call. }, // This behavior function is called when elements are removed. detach: function (context, settings) { // Do your js stuffs you want to do after your AJAX call. } }
Now, lets take a look to an example :
Suppose, we want to put some new html after our AJAX call in a div. So the code will be look like:
// JavaScript Closure to map your jQuery to '$'. ( function($) { Drupal.behaviors.yourModuleName = { attach: function (context, settings) { // Weare going to do a ajax call, using a // menuu call back. $.post( 'yourCallBackMenuPath', { // Your passsed parameters to the server side // code for your desired functionality. }, function(data){ // 'data' is the defined variable to collect the returned value // from server side code which contains some html code which // we are going replace. $('elementSelecter').html(data); } ); } } }(jQuery));
Now, you are ready to access your code after your ajax call which is safe inside the Drupal.behaviors.
WARNING :
There are some problems we might face. Never use any event call inside the Drupal.behaviors or any unnecessary js code which we can use in $(document).ready() function or we don’t want to execute after our AJAX call back.
Now the question is, why we are talking abut this. Lets take an example – if we use any click event in behaviors( which we don’t need to be executed after AJAX call ) then it will be executed( without any reason ) and will be registered into the DOM. So now, while we will be doing our actually js stuff, those registered click events would also be called and executed, which will provide a mess. So, please be sure about that.
Thanks a Lot. HAPPY DRUPALIZING 🙂
Panagiotis said:
To make sure you only act once on each request, all you have to do is use the context variable available in behaviors.
That’s true that if your code is the following, each time the behavior is called a click handler will be attached:
Drupal.behaviors.test = {
attach: function(context, settings) {
$(‘a’).click(function() {
// Handler is attached once per request
});
}
}
If you properly use the context variable though, the handler will attach only on elements found in this request:
Drupal.behaviors.test = {
attach: function(context, settings) {
$(‘a’, context).click(function() {
// Handler is attached to every element found in the context.
});
}
}
At first context equals the document. After that, the context equals the contents of the request.
Biswajit Basak said:
Hello Panagiotis,
That’s true and requirement specific. The article provides the general concept of using Drupal.behaviors.
So for the test case provided by you is absolutely correct. If anybody goes for first one obviously they will be victim of multiple click handler call. So we should go for the the 2nd one, using the context variable properly.
HAPPY DRUPALIZING 🙂