Calling a function after an #AJAX event (Drupal 7)

04/30/2013 - 23:09

Introduction

When working with Drupal 7's Form API, it's often necessaray to call a JavaScript function after the #AJAX event has fired, and Drupal 7 offers a nice mechanism to do so. This tutorial will be over a basic example on how to create a JavaScript function that is fired after an #AJAX function has completed. This is done with Drupal's Ajax Commands, and this tutorial will show how both how to use system provided callbacks, as well as define custom callbacks, to enhance 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. Without this knowledge you may find it difficult to follow along in some spots.

The setup: Register a path, and build a form

A form is required to test the code in this tutorial, by creating a form, and a path where that form can be accessed. The path is registered using hook_menu()

  1. function example_menu() {
  2. $menu['test/path'] = array(
  3. 'title' => 'Test Form',
  4. 'page callback' => 'drupal_get_form',
  5. 'page arguments' => array('example_form'),
  6. 'access arguments' => array('access content'),
  7. );
  8.  
  9. return $menu;
  10. }

And next, the form definition:

  1. function example_form($form, &$form_state) {
  2. // First create an #ajax enabled form element.
  3. $form['ajax_example'] = array(
  4. '#type' => 'select',
  5. '#title' => t('Change me'),
  6. // Set the value and the display of the elements to be the same, for convenience sake in the callback function
  7. '#options' => array(
  8. t('Select something') => t('Select something'),
  9. t('Something selected') => t('Something selected'),
  10. ),
  11. '#prefix' => '<div id="example_element_wrapper">',
  12. '#suffix' => '</div>',
  13. '#ajax' => array(
  14. 'callback' => 'example_ajax_callback',
  15. 'event' => 'change',
  16. ),
  17. );
  18.  
  19. // Next add the JavaScript file, named example.js. This file
  20. // lives in the /js folder inside the module:
  21. $form['#attached']['js'] = array(
  22. 'type' => 'file',
  23. 'data' => drupal_get_path('module', 'example') . '/js/example.js',
  24. ),
  25. );
  26.  
  27. return $form;
  28. }

 

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

The Ajax callback function

The next thing to do is create the #AJAX callback defined above, example_ajax_callback():

  1. function example_ajax_callback($form, &$form_state) {
  2. // Initialize the $commands array. This array will
  3. // contain each of the commands for the #AJAX callback:
  4. $commands = array();
  5.  
  6. // Next, create the insert function that will insert the updated content
  7. // back into the page. This is done using the system provided
  8. // ajax_command_html() function. This function is passed two values:
  9. // 1) The AJAX wrapper (defined as the #prefix and #suffix of the form element)
  10. // 2) The rendered HTML that needs to be inserted into the wrapper in the page.
  11. $commands[] = ajax_command_html('#example_element_wrapper', render($form['ajax_example']));
  12.  
  13. // Next, use the system provided ajax_command_alert() function as an example to show that the code is
  14. // working:
  15. $commands[] = ajax_command_alert(t('ajax_command_alert() is working'));
  16.  
  17. // Next include a custom function.
  18. $commands[] = array(
  19. // The command is defined in example.js
  20. 'command' => 'afterAjaxCallbackExample',
  21. // The value that the user selected in the select element is passed to the
  22. // JavaScript function:
  23. 'selectedValue' => $form_state['values']['ajax_example'],
  24. );
  25.  
  26. // Finally, return all of the commands to the system to be executed:
  27. return array('#type' => 'ajax', '#commands' => $commands);
  28. }

In the above piece of code, three actions are performed. The first inserts the HTML into the page - as you will generally do on any AJAX callback. The second uses one of the system defined ajax_command functions, as an example of how they work, and last creates the custom ajax command, to be used in the custom callback.

The JavaScript

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

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

In the above code, Drupal.ajax.commands object was prototyped with the custom ajax command, and inside that commend the value the user selected is alerted.

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

Good luck!