JQuery Theming Tips for Drupal 7


I often see posts on the drupal.org forums and elsewhere in regard to implementing jQuery scripts and code into Drupal. It seems common that users try to attach JQuery right within page.tpl.php or html.tpl.php. In other words, it's hard-coding a script into a page and it's not ideal.  Some try to render it using the PHP filter within a block or node. The disadvantages of these methods are that code added like this cannot be included in any caching or aggregation methods and can also cause conflicts that would be tricky to troubleshoot. For best Drupal theming practices, I have outlined some methods below. 

A Few Methods

There are a few methods that work well for adding additional custom JQuery scripts to Drupal 7 and some of this depends on the use case. Do you have some general code that will be used sitewide or do you have specific code that just needs to be added to the home page or a specific content type for example? Here are the two most common ways:

drupal_add_js

This method is good for one-offs such as adding code to specific pages and not the entire site. Use the drupal_add_js method by adding code to your theme's template.php file. In the snippet below, we test to see if it's the drupal home page and then if it is, add the code. 

function my_theme_preprocess_html(&$variables) {
  if (drupal_is_front_page()) {
  drupal_add_js(drupal_get_path('theme', 'my_theme') . '/js/my_script.js');
   }
}

In the above code sample, you would replace 'my_theme' with the actual machine name of your theme. 'js' is a folder within your theme folder that contains your script(s).  We can also use the drupal_add_js method to a specific content type like this:

function my_theme_preprocess_node(&$variables) {

  if (isset($variables['node']) && $variables['node']->type == 'page') {
    // Add js
    drupal_add_js(drupal_get_path('theme', 'my_theme') . '/js/scripts.js');
    $variables['scripts'] = drupal_get_js();
  }
}

This would add the script to all pages that are of content type "page".

You can also use drupal_add_js method for adding a script to one specific node path (nid).   Below we give a node id (nid) to add a custom script to a specific node path id, in this case /node/8

function my_theme_preprocess_node(&$variables) {
   if(arg(0) == 'node' && arg(1) == '8' && arg(3) == null) {
     drupal_add_js(drupal_get_path('theme', 'my_theme') . '/js/custom.js');
  }
}

Theme .info file

If you need to add a script to your entire site in every page, then you can use the above method without any conditions or you can include the script in your theme's .info file like this:

scripts[] = js/custom.js</pre>

The Code

So now you are all set adding your script but how do you format JQuery calls for Drupal 7? A lot has changed with the way in which JQuery is called in Drupal 7. In Drupal 6, we used to do something like this:

Drupal.behaviors.myfunction = function(context) {
//some jquery goodness here...
};

However, now in Drupal 7, it would look like this:

(function ($) {
  //add drupal 7 code
  Drupal.behaviors.myfunction = {
    attach: function (context, settings) {
      //end drupal calls

      //some jquery goodness here...
    }
  }
})
(jQuery);

Ajax?

One addtional hint is if you need to execute some JQuery where there is an Ajax event, you need to make JQuery aware of that. You can do that with an event handler for Ajax:

(function ($) {
  // Add drupal 7 code.
  Drupal.behaviors.MyfunctionTheme = {
    attach: function (context, settings) {
      // End drupal 7 calls.

      // Tell JQuery that there's an Ajax event first
      $('.mydiv').ajaxComplete(function () {
        // now your actual code
        $(this).remove() // or whatever code you need to execute
      });
    }
  }
})
(jQuery);

Note that I have used and tested all these methods in various sites I have designed, developed and themed. Let me know in the comments if you have any additional tips that I might have missed. Happy Drupal JQuery-ing!

Resources

Tags