jQuery and Drupal

jquery-logo.jpgDrupal and jQuery have proven to be a powerful combination when it comes to producing useful and flashy web sites and web applications. In episode 88 of the Geeks and God podcast we talk about jQuery and how it works from within drupal. Part of my homework from the episode was to write up some examples of how to use jQuery from within drupal. Here are those examples.

Add A script.js To Your Theme

As of drupal 6, if you put a script.js file in the base directory of your theme it will automatically be loaded by drupal. It operates similarly to how style.css works for css files. If you want to do the same thing in drupal 5 you can put the following code in your template.php file:

<?php
function _phptemplate_variables($hook, $vars) {
  if (
$hook == 'page') {
   
// Add the script.js file
   
drupal_add_js(path_to_theme() .'/script.js');
   
// Reload the scripts variable to include the added file
   
$vars['scripts'] = drupal_get_js();
  }
}
?>

Run JavaScript On Page Load

If you want your jQuery script to run when the page first loads your script should be in the form of something like:

Drupal 5

if (Drupal.jsEnabled) {
  $(document).ready(function () {
    // Put your javascript in here
  });
}

Drupal 6

Drupal.behaviors.myModuleBehavior = function (context) {
  // Put your javascript in here
};

myModuleBehavior should be a unique name for your module or theme. For example, the function in the comment module is Drupal.behaviors.comment.

Create A Namespace

When you go to write custom functions with jQuery you want to have a custom namespace for your functions. Drupal provides a namespace we can extend to put our functionality on. We can see an example of this on the comment module.

// This is where the namespace is created.
// When you create your own namespace change comment to be the
// name of your namespace
Drupal.comment = {};

// Here we create a function in the comment namespace.
// This should be safe from other scripts having naming conficts
Drupal.comment.getCookie = function(name) {
  // My function code here
};

Using drupal_add_js

drupal_add_js is the function that allows us to add javascript to a page in drupal. Here are a few examples of ways to add javascript.

Adding A File

We can add a javascript file to a page by simple calling:

<?php
  drupal_add_js
('path/to/file.js');
?>

If we call this more than once the file will only be added once. Drupal knows not to add the same file more than one time to a page.

Add Inline Javascript To The Head

Sometimes we want to place javascript right in the head of a page. In these cases we can do something like:

<?php
  $myjs
= "some javascript in here";
 
drupal_add_js($myjs, 'inline');
?>

When we set the second argument to inline it knows to add your javascript right into the page. The default location for this is the head.

Pass Variables from PHP to JavaScript

PHP and JavaScript use different formats for variables. drupal_add_js provides a nice way for us to pass variable information from PHP to JavaScript to use later. First, let's look at how to pass a variable to JavaScript.

<?php
  drupal_add_js
(array('myvarname' => $myvarvalue), 'setting');
?>

This will create a variable called Drupal.settings.myvarname with a value of $myvarvalue. $myvarvalue will have been converted from the PHP form of that variable to the JavaScript form. You could use that variable by doing something like:

  alert(Drupal.settings.myvarname);

This is a great way to have an external javascript file doing your work and passing variable information to it.

This is just some of the basics. There is a lot more we can do with the jQuery and drupal combination.

Great stuff as

Great stuff as usual...
Thanks again!

Nice article! Can you make

Nice article!

Can you make an example calling functions from the external javascript?

alert(Drupal.settings.myvarname) - its showing undefined :(

alert(Drupal.settings.myvarname); this is not working. Its giving undefined.

I created a node type module in that i created node.tpl.php and created a new .js file and add the following code to node.tpl.php

$str_address = $arr_venue_info->body;
drupal_add_js (drupal_get_path('module', 'event') . '/map.js');
drupal_add_js(array('myvarname' => $str_address), 'setting', 'header');

in .js file I wrote alert(Drupal.settings.myvarname);

its alerting 'undefine'

may i know the solution plz...

Top to bottom flow

Web pages have a top to bottom flow. If you put something in like...

alert(Drupal.settings.myvarname);

it might fire before that variable has been read and set. Instead I'd try something like...

$(document).ready(function () {
  alert(Drupal.settings.myvarname);
});

This will wait for the document/javascript/Drupal.settings to be ready before firing off the alert function.

add_js inline to load google's website optimizer code

Hi matt,

Thanks for your article.
Could you by any chance be so kind as to show me the way in adding the google website optimizer javscript code into the page head.

<script>
function utmx_section(){}function utmx(){}
(function(){var k='3029383398',d=document,l=d.location,c=d.cookie;function f(n){
if(c){var i=c.indexOf(n+'=');if(i>-1){var j=c.indexOf(';',i);return c.substring(i+n.
length+1,j<0?c.length:j)}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;
d.write('<sc'+'ript src="'+
'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'
+'/siteopt.js?v=1&utmxkey='+k+'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='
+new Date().valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+
'" type="text/javascript" charset="utf-8"></sc'+'ript>')})();
</script><script>utmx("url",'A/B');</script>

This code has to be loaded inline into page heading for one page only. (i have tried using this code in a .js, which was of no avail). I'm lacking in the skills department for both php and js.

Do you see any usable solution here?

Thanks a bunch in advance!

call it via inline

One of the ways to use drupal_add_js is to provide inline code. Its usage is as follows:

<?php
drupal_add_js
('my javascritp code here', 'inline');
?>

The snippet you provided would the the javascript code to enter.

Drupal.settings

I have a list block produced by a view:
item category1
items
item category2
...

In the header of the view I have PHP code that passes the name of one of the items to my list such that I can collapse/hide other items based upon the argument passed. Pseudo code:

drupal_add_js(path_to_theme() . 'path/to/accordion.js', 'theme');
drupal_add_js(array('myvar=>ucwords(arg(2))', 'setting'));

In my accordion.js file I have:
$(document).ready(function(){
alert(Drupal.settings.myvar);  //to show that the value is passed
$('h3:contains(Drupal.settings.myvar)').next('ul').toggle();
});

The wacky thing is that alert(); returns the value passed from PHP in the header of my block...but I get nothing at the next step where I call Drupal.settings.myvar for jQuery.

Any suggestions? I'm close to suicide ;)

Im retarded...

i wasnt escaping the Drupal.settings.myvar out of the string in:

$('h3:contains(Drupal.settings.myvar)').next('ul').toggle();

Great article BTW ;)