with one click
drupal-form-ajax
Drupal AJAX form callbacks,
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Drupal AJAX form callbacks,
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
HTMX in Drupal 11.3+ core — the Htmx PHP fluent builder, dynamic forms with swapOob, partial routes with _htmx_route, response headers, and Drupal.behaviors integration. Use when building interactive UI without full-page reloads using Drupal's native HTMX support.
DDEV local development expertise. Use when working with DDEV projects, containers, configuration, or troubleshooting DDEV environments.
Custom Docker Compose local development patterns. Use when working with Docker-based local environments, container configuration, or troubleshooting Docker setups.
Drupal access control — permissions.yml, access callbacks, AccessResult, custom access checkers, and entity access.
Drupal Cache API — cache tags, contexts, max-age, cache bins, invalidation, and adding cache metadata to render arrays.
Drupal Composer management — requiring modules, updates, patches via composer-patches, and version constraints.
| name | drupal-form-ajax |
| description | Drupal AJAX form callbacks, |
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['type'] = [
'#type' => 'select',
'#title' => $this->t('Type'),
'#options' => ['a' => 'Type A', 'b' => 'Type B'],
'#ajax' => [
'callback' => '::updateOptions',
'wrapper' => 'options-wrapper',
'event' => 'change',
],
];
$form['options_wrapper'] = [
'#type' => 'container',
'#attributes' => ['id' => 'options-wrapper'],
];
$type = $form_state->getValue('type', 'a');
$form['options_wrapper']['value'] = [
'#type' => 'textfield',
'#title' => $this->t('Value for @type', ['@type' => $type]),
];
return $form;
}
public function updateOptions(array &$form, FormStateInterface $form_state): array {
return $form['options_wrapper'];
}
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\MessageCommand;
public function ajaxCallback(array &$form, FormStateInterface $form_state): AjaxResponse {
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand('#my-wrapper', $form['my_element']));
$response->addCommand(new HtmlCommand('#message', $this->t('Updated!')));
$response->addCommand(new InvokeCommand('#my-input', 'val', ['new value']));
$response->addCommand(new MessageCommand($this->t('Success!'), NULL, ['type' => 'status']));
return $response;
}
'#ajax' => [
'callback' => '::myCallback', // Method or [ClassName, 'method']
'wrapper' => 'wrapper-id', // DOM ID to replace/update
'event' => 'change', // JS event (change, click, blur, etc.)
'method' => 'replaceWith', // replaceWith, append, prepend, etc.
'effect' => 'fade', // none, slide, fade
'progress' => [
'type' => 'throbber', // throbber or bar
'message' => NULL,
],
'url' => NULL, // Custom URL (leave NULL for default)
'options' => [], // Additional jQuery.ajax options
],
public function submitForm(array &$form, FormStateInterface $form_state): void {
$form_state->setRebuild(TRUE);
}