Drupal 6

This tutorial is on how to call a JavaScript function after a Drupal 7 #AJAX event. You can view the tutorial on how to call a JavaScript function after a Drupal 6 #AHAH event here: Calling a custom function after an #AHAH event

Introduction

When working with Drupal 7's Form API, I often need to call a JavaScript function after the #AJAX event has fired. This was quite difficult in Drupal 6, but Drupal 7 offers a nice mechanism to do so. In this tutorial, we will be going over a basic example on how to create a JavaScript function that is fired after an #AJAX function has completed. To do so, we will be looking at Drupal's Ajax Commands, and how we can use the system provided callbacks, as well as define our own custom callbacks, to enhance our Drupal forms.

Requirements

To understand this tutorial, you will need a strong understanding of how to build Drupal modules, how the Drupal form API works, how the Drupal #AJAX mechanism works, and how to add JavaScript to pages. I won't be going into a lot of detail on what exactly I am doing with these points as I go along, so without this knowledge you may find it difficult to follow along in some spots.

The setup: Register a path, and build a form

The first thing we need to do is build a form that we can use for the tutorial. So we will register a path allowing us to access the form. In this example, we will be creating a module named after_ajax. First, our hook_menu() implementation:

<?php
function after_ajax_menu()
{
    
$menu['after_ajax'] = array
    (
        
'title' => 'After Ajax example',
        
'page callback' => 'drupal_get_form',
        
'page arguments' => array('after_ajax_form'),
        
'access arguments' => array('access content'),
    );
    return 
$menu;
}
?>

And next, our form definition:

<?php
function after_ajax_form($form, &$form_state)
{
    
// First we create a form element with AJAX enabled
    
$form['ajax_example'] = array
    (
        
'#type' => 'select',
        
'#title' => t('Change me'),
        
// Note that I am setting the value and the display of the elements to be the same, for convenience sake in our callback function
        
'#options' => array(t('Select something') => t('Select something'), t('Something selected') => t('Something selected')),
        
'#prefix' => '<div id="after_ajax_element_wrapper">',
        
'#suffix' => '</div>',
        
'#ajax' => array
        (
            
'callback' => 'after_ajax_ajax_callback',
            
'event' => 'change',
        ),
    );
 
    
// Next we add our JavaScript file, named after_ajax.js. This file
    // lives in the /js folder inside our module:
    
$form['#attached']['js'] = array
    (
        array
        (
            
'type'  => 'file',
            
'data' => drupal_get_path('module''after_ajax') . '/js/after_ajax.js',
        ),
    );
    return 
$form;
}
?>

So at this point, we have created a menu path at /after_ajax, and a form that has a single select element that will fire an #AJAX event when the select element is changed. We have also added a JavaScript file that will contain our custom functions to be called after the #AJAX event is complete.

The Ajax callback function

The next thing we need to do is create our #AJAX callback that we defined above, after_ajax_ajax_callback():

<?php
function after_ajax_ajax_callback($form, &$form_state)
{
    
// First, we initialize our $commands array. This array will
    // contain each of the commands we want to fire for our
    // #AJAX callback:
     
$commands = array();
 
    
// Next, we create our insert function that will insert our updated content
    // back into the page. To do this, we use the system provided
    // ajax_command_html() function. We pass this function two values:
    // 1) Our AJAX wrapper (that we defined as the #prefix and #suffix of our form element)
    // 2) The rendered HTML that needs to be inserted into the wrapper in the page.
    
$commands[] = ajax_command_html('#after_ajax_element_wrapper'render($form['ajax_example']));
 
    
// Next, we will use the system provided ajax_command_alert() function as an example to show it's
    // working:
    
$commands[] = ajax_command_alert(t('ajax_command_alert() is working'));
 
    
// Next we will include a custom function that we will call ourselves in our JavaScript file:
    
$commands[] = array
    (
        
// The command will be used in our JavaScript file (see next section)
        
'command' => 'afterAjaxCallbackExample',
        
// We pass the value that the user selected in the select element to our
        // JavaScript function:
        
'selectedValue' => $form_state['values']['ajax_example'],
    );
 
    
// And finally, we will return all of our commands to the system to be executed:
    
return array('#type' => 'ajax''#commands' => $commands);
}
?>

In the above piece of code, we perform three actions. The first is to insert our HTML into the page - as you will generally do on any AJAX callback. The next is to use one of the system defined ajax_command functions, as an example of how they work, and last we create our own ajax command, to be used in our callback.

The JavaScript

The last thing we need to do is define our custom JavaScript command, afterAjaxCallbackExample, that we used in our Ajax Callback function above. This code is defined in oiur after_ajax.js file that we included in our form definition:

  1. (function($, Drupal)
  2. {
  3. // Our function name is prototyped as part of the Drupal.ajax namespace, adding to the commands:
  4. Drupal.ajax.prototype.commands.afterAjaxCallbackExample = function(ajax, response, status)
  5. {
  6. // The value we passed in our Ajax callback function will be available inside the
  7. // response object. Since we defined it as selectedValue in our callback, it will be
  8. // available in response.selectedValue. Usually we would not use an alert() function
  9. // as we could use ajax_command_alert() to do it without having to define a custom
  10. // ajax command, but for the purpose of demonstration, we will use an alert() function
  11. // here:
  12. alert(response.selectedValue);
  13. };
  14. }(jQuery, Drupal));

In the above code, we prototyped the Drupal.ajax.commands object with our custom function, then inside that function we used the value we passed to display the selected value to the user.

And that's that! Now whenever we need to call a function after an #AJAX event, we can either use a pre-defined, system-provided ajax_command function, or we can define our own custom function when no system function exists!

Good luck!