Backend Development Topic - AJAX API

Drupal’s AJAX API allows parts of a page or form to update without a full page reload. It is built directly into the Form API (FAPI) and tightly integrated with render arrays, routes, and controllers.

In backend terms, AJAX in Drupal is not about JavaScript first. It is about server-side state changes that return updated render arrays. Drupal handles the JavaScript layer for you.

This article continues the learning-by-building approach by extending the same weeklydrupal_demo module. We will focus on how AJAX works internally, how to implement it correctly, and where it fits in backend architecture.


1. What the Drupal AJAX API Is

The Drupal AJAX API:

  • Sends a request to the server
  • Rebuilds part of a form or page
  • Returns commands to the browser
  • Updates the DOM automatically

In simple terms:

Drupal AJAX lets the server decide what changes, not the browser.

This keeps logic centralized and consistent.


2. When to Use Drupal AJAX

Use Drupal AJAX when:

  • A form field controls other fields
  • You need conditional logic based on user input
  • You want to update part of a form dynamically
  • The state must be validated server-side

Avoid Drupal AJAX for purely visual effects.


3. How Drupal AJAX Works (High Level)

  1. User interacts with a form element
  2. Drupal sends an AJAX request
  3. Form is rebuilt on the server
  4. AJAX commands are returned
  5. Browser updates only the targeted area

The same form logic runs again on the server.


4. Basic AJAX Form Example

We will extend the weeklydrupal_demo module with a simple AJAX-enabled form.

Form class

weeklydrupal_demo/src/Form/AjaxDemoForm.php
<?php

namespace Drupal\weeklydrupal_demo\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class AjaxDemoForm extends FormBase {

  public function getFormId() {
    return 'weeklydrupal_demo_ajax_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['choice'] = [
      '#type' => 'select',
      '#title' => $this->t('Choose an option'),
      '#options' => [
        'a' => 'Option A',
        'b' => 'Option B',
      ],
      '#ajax' => [
        'callback' => '::updateMessage',
        'event' => 'change',
        'wrapper' => 'ajax-message-wrapper',
      ],
    ];

    $form['message'] = [
      '#type' => 'container',
      '#attributes' => ['id' => 'ajax-message-wrapper'],
    ];

    $value = $form_state->getValue('choice');

    if ($value) {
      $form['message']['text'] = [
        '#markup' => $this->t('You selected: @value', ['@value' => $value]),
      ];
    }

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    // No submit logic needed for this demo.
  }

  public function updateMessage(array &$form, FormStateInterface $form_state) {
    return $form['message'];
  }

}

5. Understanding the #ajax Property

'#ajax' => [
  'callback' => '::updateMessage',
  'event' => 'change',
  'wrapper' => 'ajax-message-wrapper',
]

Explanation:

  • callback – Method that returns updated render array
  • event – Browser event that triggers AJAX
  • wrapper – HTML ID to replace

Drupal handles the JavaScript automatically.


6. The AJAX Callback

public function updateMessage(array &$form, FormStateInterface $form_state) {
  return $form['message'];
}

Important rules:

  • Callback returns a render array
  • No HTML is echoed
  • Drupal converts it into AJAX commands

7. Wrappers and IDs

The wrapper ID must:

  • Exist in the form
  • Be unique on the page
  • Match the wrapper value
'#attributes' => ['id' => 'ajax-message-wrapper'],

If the ID does not match, the update will fail.


8. AJAX and Form Rebuilds

Every AJAX request causes a form rebuild.

Drupal:

  • Preserves form state
  • Re-runs buildForm()
  • Applies validation when needed

This ensures consistent behavior between normal and AJAX submissions.


9. AJAX vs Custom JavaScript

Drupal AJAX:

  • Is server-driven
  • Respects access control
  • Integrates with caching
  • Works with validation

Custom JavaScript:

  • Is client-driven
  • Bypasses Drupal state
  • Can cause inconsistencies

Use Drupal AJAX when backend logic matters.


10. Common Mistakes to Avoid

  • Returning strings instead of render arrays
  • Forgetting wrapper IDs
  • Mixing JavaScript logic with PHP logic
  • Using AJAX where a simple form rebuild is enough

AJAX should simplify UX, not complicate logic.


11. Learning by Building: weeklydrupal_demo

At this point, our demo module includes:

  • Custom routes
  • Controller responses
  • Custom forms
  • Form alters
  • AJAX-enabled interactions

Each concept builds on the previous one.


12. Why the AJAX API Matters

Understanding Drupal AJAX helps you:

  • Build dynamic forms safely
  • Keep logic on the server
  • Avoid fragile JavaScript hacks
  • Scale complex user interactions

This is a key backend skill.