Useful features in the Drupal Javascript system

June 18, 2021


Table of contents

Quick Access

Drupal has a very useful Javascript system that allows back end developers to communicate with the front end side of things. It really helps us to forget about all the plumbing you would need to build to pass data back and forth, especially if your app makes heavy use of AJAX. There are three features that I find particularly useful.

Javascript Settings

One of the features of Drupal’s Javascript system that I really like is dynamically passing settings from Drupal to the Javascript that runs on the browser. All that you require to pass setting variables is one line of code:

drupal_add_js(array('ajax_example' => array('some_setting' => 'value')), 'setting');

The ajax_example key lets Drupal know that you want the settings variables set within the context of your ajax_example.

Suppose you need some charts for representing usage statistics on your web application. You decide to use a Javascript charting library. How would you pass your usage data to the charting library? You could set up an endpoint that the script could call to get the data via JSON or XML but Drupal Javascript settings has you covered. Generate the data when the user is making the page request and pass it along to your script. Boom. You have the data already there, ready to use. All in one or two lines of code.

AJAX Commands

AJAX commands allow a backend programmer to call a function in the front end, add some HTML, hide some HTML, or any number of different things you’d want the front end to do for you. In fact, Javascript settings are passed to the front end Javascript via AJAX commands. Pretty neat how everything ties up nicely, right?

function ajax_example_some_ajax_callback($form, &$form_state) {
  // Some variable setup code here.

  // Prepare the AJAX commands to send to the front end.
  $commands = array();
  $commands[] = ajax_command_html('.container', $some_new_html); // Insert some HTML inside a container.
  $commands[] = ajax_command_replace('.to-be-replaced', $replacement_html); // Replace some HTML with some other HTML.
  $commands[] = ajax_command_remove('.elements-to-remove'); // Remove an element.
  $commands[] = ajax_command_invoke(NULL, 'someJSFunction'); // Run a function on the Javascript side.

  // Send all the commands to the front end.
  return array(
    '#type' => 'ajax',
    '#commands' => $commands

As you can see, we can send any number of commands to the front end using this method. It’s really easy to do and very convenient.

Form API: #ajax

Drupal’s Form API has a handy property that you can set in your form elements to let Drupal and the front end Javascript that you want that form element to be handled via AJAX calls.

function ajax_example_graphs_form($form, &$form_state,) {
  // Some form element code goes here...

  // Tell Drupal that you want some button to be handled via AJAX.
  $form['some_button'] = array(
    '#type' => 'button',  // The form element is a button.
    '#value' => t('Show Graphs'),  // The label that that button is going to have.
    '#ajax' => array(
      'call_back' => 'ajax_example_graphs_form_show_graphs_callback', // Name of the function that will handle sending AJAX commands back to the browser
      'wrapper' => 'graph-container', // The results of the AJAX call will be placed in this container.

As you can see, with a simple #ajax property, we are able to tell Drupal a lot. We’ve told it to handle the Show Graphs button via AJAX, that the code that will handle the rendering logic will be ajax_example_graphs_form_show_graphs_callback, and finally that the result should replace the container with id ‘graph-container’. This saves a lot of time and effort by preventing developers from creating plumbing code.

From a Business Perspective

The Drupal Javascript system makes things easier for developers to get things done. This translates into a potentially huge productivity boost as brain cycles are used to find solutions to business problems instead of dealing with boilerplate or glue code.