If you are new to Drupal Behaviors, this is a short introduction on why you should use this fairly simple feature and Dejan Dudukovic, EtonDigital’s front end developer, will explain you how.

What is Drupal Behaviors?

Drupal Behaviors is the object in JavaScript that Drupal initializes after page load, and after every AJAX call in DOM (Document Object Model).

Behaviors allow us to perform better and easier integration of JavaScript in Drupal projects, forcing developers to follow the coding standards.

How to use Drupal Behaviours?

Drupal’s official JavaScript documentation suggests that modules should implement JavaScript by attaching logic to Drupal.

Here is an example:


Drupal.behaviors.exampleModule = {                             
    attach: function (context, settings) {                       
      $('.example', context).click(function () {                 
        $(this).next('ul').toggle('show');                       
      });                                                        
    }                                                            
  }; 


Drupal core will call attached behaviors when the DOM is fully loaded, passing in two arguments:

  1. Context: which contains the DOM (the object representation of the HTML where some changes via Ajax are committed)
  1. Settings: which contain all the settings injected server side (the variable that contains all parameters/options that are called from Drupal)

Drupal behaviors work only on native Drupal ajax call, but if we have custom Ajax call and need to init behavior after Ajax, we must re-initialize behavior in our code.


Drupal.attachBehaviors(document, Drupal.settings);


However, you may only need to apply a JavaScript behavior one time. In most cases, your JavaScript seems to be executing fine, but sometimes things seem to be executing two times or more. Have you noticed?

This may be triggered by some type of AJAX call that causes your JavaScript behaviors to get executed again, on every request.

For many reasons, this, certainly, is an issue, but fortunately, Drupal 7 makes it easy to fix it with jQuery ‘Once’ plugin.

What is jQuery Once method?

Drupal 7 integrates Jquery ‘Once’ plugin into Drupal 7 core and the plugin adds a simple class to the HTML element to ensure that the behavior is only processed one time.


Drupal.behaviors.globalHideMenu = {                                        
  attach: function (context, settings) {                                   
    $('.nav-flyout', context).once('remove-modals', function () {          
      $(document).keyup(function (e) {                                     
        if (e.keyCode == 27) {                                             
          $('.nav-flyout', context).removeClass('js-flyout-active');       
        }                                                                  
      });                                                                  
    });                                                                   
  }                                                                        
};

The above code will add a class remove-modals-processed the first time it runs. The next time that Drupal.attachBehaviors() is called, .Once() will find the class and skip.

Let’s take a look at this example:


$('.spelling-suggestions', context).once('spelling-linkoptimize', function() {      
  var url = window.location.href;                                                   
      queryString = url.split('?')[1];                                              
  $(this).find('a').each(function() {                                               
    var thisHref = $(this).attr('href');                                            
    thisHref = thisHref + "?" + queryString;                                       
    $(this).attr('href', thisHref );                                                
  });                                                                               
}); 


In this example, we need to add queryString on every link within “spelling-suggestions” element, and to check whether a “spelling-suggestions” class is in the “context” element.

So, we use .Once to make sure that this function will be processed just one time on the given element making a “spelling-linkoptimize” class.


$('.spelling-suggestions', context).once('spelling-linkoptimize', function()... 

Place url href in the variable, parse it, and take everything that shows after the character “?” queryString.


 var url = window.location.href;                                                   
      queryString = url.split('?')[1]; 


$(this) shows the element where we execute the function, in our example, that’s ‘.spelling-suggestions’ which is a part of the context. We can then search all links within that element and add queryString we took from URL.

$(this).find('a').each(function() {                                               
  var thisHref = $(this).attr('href');                                            
  thisHref = thisHref + "?" + queryString;                                        
  $(this).attr('href', thisHref );                                               
});


This way we are able to perform re-initialization during Ajax requests, implement the desired functionality to the elements and avoid processing the same element multiple times while making sure the functionality is performed on the new elements after an Ajax request.

Moreover, we reduce the number of performed functions and ensure that the code is executed only when needed.

Doing so we reduce resources which are especially important when working in Javascript as we need to pay attention to performance.

Drupal Behaviors come in handy while working on different projects as the feature provides a better way for attaching Javascript functionality.

So, why should you use Drupal Behaviors?

  • ability to override Javascript
  • ability to attach behaviors to a specific context

Moreover, we can see many benefits using this feature, such as, firstly, better performance and easier maintenance of the code, especially when working in a big team, and modular Javascript development.

As we need to write an optimal and a better-optimized code to make sure the applications can work fast and smooth, in short, Drupal Behaviors allow us to override/extend the existing behavior. The advantage is that they are automatically re-applied to any content that is loaded through Ajax.

If you have any questions, feel free to post in the comments.