Simple AJAX Example for Drupal 6 and 7

Submitted by Daniel Henry on 09/25/2012 - 03:24:pm

Step 1 Create A Module.

It should go without saying but I find many of those asking for help on ajax are not sure what to do with all the hooks and such necessary to implement an ajax callback. So here it is from the beginning. If you know how to create a module already, skip this step or copy the code for a fully functional example module.

Create a folder in the path “/sites/all/module/custom/” called “ajax_example”. All paths are relative to the Drupal installation root usually something like: /var/www/html/sitename

In that folder create an info file named “ajax_example.info” and paste the following code into that file exactly as listed:

  1. name = AJAX Example
  2. description = An ajax callback example.
  3. project = Custom
  4. core = 7.x

This information will be displayed in the Drupal modules page.

Create a couple empty files named “ajax_example.module” and “ajax_example.js”. Just leave them as empty files for now.

Step 2 Set up the menu hook

Open the ajax_example.module file in your favorite code editor.

Set up a url of the ajax callback by implementing Drupal's hook_menu. This is how Drupal will pass information to javascript. Create the menu hook by pasting this code into the ajax_example.module file:

  1. /**
  2.  * Implements hook_menu().
  3.  */
  4. function ajax_example_menu() {
  5.  
  6.   // Ajax Callback. Returns telephone number for current region.
  7.   $items['ajax/username'] = array(
  8.     'title' => 'Get Current User Name',
  9.     'page callback' => 'ajax_example_get_username',
  10.     'access arguments' => array('access content'),
  11.     'type' => MENU_CALLBACK,
  12.   );
  13.  
  14.   return $items;
  15. }

Drupal’s hook_menu defines url’s for the system. The array offset ‘ajax/username’ is the actual url the ajax code will call. The page callback is the function that will retrieve the information. The rest of these options can be researched at api.drupal.org.

Step 3 Create the callback function

Next task is to return the information the ajax call wants. Still in our module file, create the function named in the page callback.

  1. /**
  2.  * AJAX function that returns the current logged in users name.
  3.  */
  4. function ajax_example_get_username() {
  5.  
  6.   // Get currently logged in user.
  7.   global $user;
  8.   $user_name = $user->name;
  9.  
  10.   // Drupal 7 Old School.
  11.   print $user_name;
  12.   drupal_exit();
  13.  
  14.   // Drupal 7 New School.
  15.   drupal_json_output($user_name);
  16.  
  17.   // Drupal 6.
  18.   print $user_name;
  19.   module_invoke_all('exit');
  20.   exit;
  21. }

This function varies a bit from Drupal 6 and Drupal 7 so both are included. Only use the code that is associated with your version of Drupal.

First the function retrieves the information. In this example it’s just the currently logged in users name. But any information can obtained. The function can run raw queries, pull globals, generate entire pages, or just return some random text.

The return is the important piece. Do not try to send the data with a return statement. Drupal assumes that information called by a menu hook is a page. Any information returned will be wrapped with the default page template. This is usually not desired for an ajax function.

So instead pass the info to jQuery with a standard “print”. Also note that even if the function does not return a value if the function returns at all the page template will be printed to the screen by the menu system. In order to prevent the page template from being outputted the function should be exited stopping any further html generation. The exit is a little different in Drupal 6 and 7. Several clean-up tasks are good to perform before killing Drupal.  In Drupal 6 these clean-up tasks are signaled with a call to “module_invoke_all(‘exit’)”. This just calls any exit hooks implemented on the current Drupal system. The function drupal_exit in Drupal 7 calls the hook invoke and the php exit making the code a little cleaner and passing the responsibility of clean-up to Drupal’s core.

Step 4 Write your ajax function

Now for the actual ajax function. Here I am using jQuery as it makes ajax and javascript much easier to work with. Like the exit functions above Drupal 6 and 7 differ slightly in how they implement jQuery files. Paste the appropriate code snippet for your version of Drupal into the .js file created earlier.

Drupal 6

  1. Drupal.behaviors.ajax_example = function (context) {
  2.  
  3.   // If the site name is present set it to the username.
  4.   if ($('#site-name', context).length) {
  5.     $.ajax({
  6.       url: '/ajax/username',
  7.       success: function(data) {
  8.         // Change site name to current user name.
  9.         $('#site-name a span').html(data + '.com');
  10.      }
  11.     });
  12.   }
  13. }

Drupal 7

  1. (function ($) {
  2.   Drupal.behaviors.ajax_example = {
  3.     attach:function (context) {
  4.  
  5.       // If the site name is present set it to the username.
  6.       if ($('#site-name', context).length) {
  7.         $.ajax({
  8.           url: '/ajax/username',
  9.           success: function(data) {
  10.  
  11.             // Change site name to current user name.
  12.             $('#site-name a span').html(data + '.com');
  13.          }
  14.         });
  15.       }
  16.     }
  17.   }
  18. })(jQuery);

Make sure the behavior name is unique. In this case the behavior name is the name of the module “ajax_example”. In Drupal 7 the “attach: function” is used instead of the “= function” syntax. Once inside these blocks the code is the same. This code simply checks if the site name is present. If so change the site name to the current users name. Not a very practical use of ajax but this is just meant as an example.

Step 5 Load the javascript file

Once the javascript file is finished it needs to be included in the appropriate pages. This can be done through a block hook, a page hook, a node api hook, or anything that determines a page's content. Since this specific example affects all pages on the site I’m going to make the rather poor choice of adding it in the init hook. If your ajax only affects one page use a hook that specifies that page as hook_init runs on every page load and can affect overall site performance.

  1. /**
  2.  * Implementation of hook_init().
  3.  */
  4. function ajax_example_init() {
  5.  
  6.   // Drupal 6: Add our own CSS and JS to the site.
  7.   drupal_add_js(drupal_get_path('module', 'ajax_example') . '/ajax_example.js');
  8.  
  9.   // Drupal 7: Add our own CSS and JS to the site.
  10.   drupal_add_js(drupal_get_path('module', 'ajax_example') . '/ajax_example.js', array('scope' => 'footer'));
  11. }

The only difference between Drupal 6 and 7 is the scope parameter. It’s always a good idea to throw custom js in the footer. It makes sure if any 3rd party services being accessed by your callback are down the page will still loads. Also it ensures the content the js triggers on is also loaded.

Finish Up

And there you have it. Enable the module and watch your site name change to the current logged in user’s name. Of course with JavaScript you can trigger off of a button press, search box edit, select box choice, or any of the events supported in the language.