Creating a Custom Ajax Command in Drupal 8

Drupal 8 provides the option to include an Ajax Callback within our applications using the Ajax Framework. There are some existing functions which can be used: Methods to hide/show elements in the html document, attach content to an element, redirect a page after a submit, and so on. Sometimes we need to implement something particular, or a custom JS code. In that case, those out-of-the-box functions are not enough. Fortunately, we can also create our own custom responses. So, let’s start creating a new ajax callback for a custom form submission.

Since now we are using Drupal 8, we can take advantage of the Drupal Console to easily generate the necessary boilerplate code. That said, before continue make sure you have the latest console version (1.6.0) if you do not have it yet, you can follow instructions at the official docs page.

Generating the custom Module

The first step is to define the module where code will be generated. If you don't have a custom module, you can create a new one executing the following Drupal Console command:

The render() method must return a render array. In this case, 'example' will be the javascript command which we will invoke later inside the *.js file. We can define other properties on this response, for example a custom message.

The JavaScript file

Now let's take a look to the second generated file, example.js, which is located inside your custom module. Here, we are reading the message property from the response object and displaying the result in the browser's console. This is a really basic example, but you can implement a more robust actions depending on your requirements in fact we could reuse AJAX functions from core to interact with our response.

The library definition file

The library definition tells Drupal what javascript file(s) need to be loaded, and where and where to find them relative to the module’s directory. We can also define any required dependencies -- such as core/drupal.ajax above -- by defining the dependencies key.

Invoking our custom command

First we need to attach the library to the rendered page. There are lots of ways to do this. For this post, we want to attach it to a specific form. So, we’ll define a form alter:

function custom_form_alter(&$form, FormStateInterface $form_state, $form_id) {
/**
* Apply the form_alter to a specific form #id
* the form #id can be found through inspecting the markup
*/
if ($form['#id'] == 'custom-form') {
/**
* Include a js, which was defined in example.libraries.yml
*/
$form['#attached']['library'][] = "example/example-library";
}
}

We alter the $form array by adding a new item under #attached. Since we’re attaching a library, we also use the library key. Finally, we specify our module name (example) and then our library name (example-library).

The above only attaches all the necessary Javascript. Now we need to put it to use! To do that, we need to modify the submit callback of the form to add our custom AJAX command:

To add our command, we need to tell Drupal to only return AJAX content, rather than a full web page. In the form submit function we create a new AjaxResponse and call the addCommand() method to add our custom command.

Put together, our custom ajax command will be triggered every time the exampleSubmitForm() method is called, and our custom message will appear in the browser’s console.

Wrap up

While Drupal Console makes creating a new AJAX command easy, you can also do it manually:

Create a custom command class extending AjaxInterface.

Invoke the Drupal.AjaxCommands.prototype object and define there your custom actions.