Skip to header Skip to main navigation Skip to main content Skip to footer
  • Log in
Home
DrupalVIP
Freelancer service with great care and enthusiasm.
  • Home
  • Products
  • Blog
  • Support
    • Dictionary
    • Drupal Resources
    • External Resources

Select Element with AJAX updating form dynamically

Breadcrumb

  • Home
  • DrupalVIP Support
  • Select Element with AJAX updating form dynamically

Adding AJAX callback events to form fields allows to dynamically update fields and other markup, while users interact with the forms.

AJAX callback functions on forms can be used to:

  • Update existing or add new form fields,
  • update values in form fields
  • execute a variety of predefined AJAX commands or
  • run custom JavaScript code

 

The typical steps involved:

  1. Create a new form or use hook_form_alter to change an existing form.
  2. Add an '#ajax' render element to a field that should trigger a callback function.
  3. Define name of the callback function and type of event that will use it.
  4. When the event is triggered by changing a form field's value the browser triggers an AJAX request
  5. Drupal receives the AJAX request and rebuilds the form. Using the information provided by the AJAX request data the form will have the required modification (one more element in a multi valued element, for example).
  6. After the form is rebuilt, the callback function is called to build the response to the AJAX callback.
  7. The callback function allows accessing the $form array and the FormStateInterface and must finally return a render array or some HTML markup or can execute an AJAX Command.

 

I copied a good example of implementing ajax support in few steps.

 

step 1: creating the route the the ajax form

drupalvip.ajax_form:
  path: '/ajax-form'
  defaults:
    _form: '\Drupal\drupalvip\Form\AjaxForm'
    _title: 'Ajax form'
  requirements:
    _permission: 'access content'

 

step 2: implementing the form object

<?php

namespace Drupal\drupalvip\Form;

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

class AjaxForm extends FormBase {

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

  public function buildForm(array $form, FormStateInterface $form_state) {
    $triggering_element = $form_state->getTriggeringElement();

    $form['country'] = [
      '#type' => 'select',
      '#title' => $this->t('Country'),
      '#options' => [
        'serbia' => $this->t('Serbia'),
        'usa' => $this->t('USA'),
        'italy' => $this->t('Italy'),
        'france' => $this->t('France'),
        'germany' => $this->t('Germany'),
      ],
      '#ajax' => [
        'callback' => [$this, 'reloadCity'],
        'event' => 'change',
        'wrapper' => 'city-field-wrapper',
      ],
    ];

    $form['city'] = [
      '#type' => 'select',
      '#title' => $this->t('City'),
      '#options' => [
        'belgrade' => $this->t('Belgrade'),
        'washington' => $this->t('Washington'),
        'rome' => $this->t('Rome'),
        'paris' => $this->t('Paris'),
        'berlin' => $this->t('Berlin'),
      ],
      '#prefix' => '<div id="city-field-wrapper">',
      '#suffix' => '</div>',
      '#value' => empty($triggering_element) ? 'belgrade' : $this->getCityForCountry($triggering_element['#value']),
    ];

    return $form;
  }

  public function reloadCity(array $form, FormStateInterface $form_state) {
    return $form['city'];
  }

  protected function getCityForCountry($country) {
    $map = [
      'serbia' => 'belgrade',
      'usa' => 'washington',
      'italy' => 'rome',
      'france' => 'paris',
      'germany' => 'berlin',
    ];

    return $map[$country] ?? NULL;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {  }

} // end of class

 

A few notes for your attention:

  • review the property: ajax, on the first select element
            '#ajax' => [
              'callback' => [$this, 'reloadCity'],
              'event' => 'change',
              'wrapper' => 'city-field-wrapper',
            ],
    the #ajax property include the callback method, the event in which it will be triggered and the section it will look for the change
  • The element that will be changed is defined by section element
          '#prefix' => '<div id="city-field-wrapper">',
          '#suffix' => '</div>',
  • The callback is declared like any submit method:
    public function reloadCity(array $form, FormStateInterface $form_state)
  • The submitForm method is empty, and even though it will not being used it must be implemented
    public function submitForm(array &$form, FormStateInterface $form_state) {  }
  •  

Drupal Development

Drupal Development
Code Snippet
<?php
  namespace Drupal\drupalvip\Form;

  use Drupal\Core\Form\FormBase;
  use Drupal\Core\Form\FormStateInterface;
  
  class AjaxForm extends FormBase {    

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

    public function buildForm(array $form, FormStateInterface $form_state) {
      $triggering_element = $form_state->getTriggeringElement();

      $form['country'] = [
        '#type' => 'select',
        '#title' => $this->t('Country'),
        '#options' => [
          'serbia' => $this->t('Serbia'),
          'usa' => $this->t('USA'),
          'italy' => $this->t('Italy'),
          'france' => $this->t('France'),
          'germany' => $this->t('Germany'),
        ],
        '#ajax' => [
          'callback' => [$this, 'reloadCity'],
          'event' => 'change',
          'wrapper' => 'city-field-wrapper',
        ],
      ];

      $form['city'] = [
        '#type' => 'select',
        '#title' => $this->t('City'),
        '#options' => [
          'belgrade' => $this->t('Belgrade'),
          'washington' => $this->t('Washington'),
          'rome' => $this->t('Rome'),
          'paris' => $this->t('Paris'),
          'berlin' => $this->t('Berlin'),
        ],
        '#prefix' => '<div id="city-field-wrapper">',
        '#suffix' => '</div>',
        '#value' => empty($triggering_element) ? 'belgrade' : $this->getCityForCountry($triggering_element['#value']),
      ];

      return $form;
    }

    public function reloadCity(array $form, FormStateInterface $form_state) {
      return $form['city'];
    }

    protected function getCityForCountry($country) {
      $map = [
        'serbia' => 'belgrade',
        'usa' => 'washington',
        'italy' => 'rome',
        'france' => 'paris',
        'germany' => 'berlin',
      ];
      return $map[$country] ?? NULL;
    }

    public function submitForm(array &$form, FormStateInterface $form_state) {  }

} // end of class
Read More
Form API Workflow
AJAX Forms
AJAX dependent select in Drupal 8 and 9
Basic Concepts
Tags
Drupal Support
Drupal 10
Ajax
Ajax Form
Select Element
AjaxResponse
Form Elements
Code Snippet
getTriggeringElement

The Freelancer Assistance

Proactive Maintenance

Proactive Maintenance

Drupal Training

drupal training session

Fullstack Service

Fullstack Service

Site Management

Site Management

Drupal Shared Space

Drupal Shared Space

Drupal Development

Drupal Development
Review All Services

Buy Hourly Support

 

Drupal platform support for complex websites. The service includes support, training, troubleshooting, fixes, updates, tool creation and module building.
* Minimum order is for 5 hours of support
* For every 20 hours of order you will be entitled to an additional hour of support
* For every 50 hours of order you will be entitled to 5 additional hours of support

 

>> Payment <<

 
cards

מופעל על-ידי paypal

Legal

  • Home
  • Contact
  • Products

Footer menu

  • Home
  • Contact
  • Products

Copyright © 2026 DrupalVIP project of Automatic Frameworks - All rights reserved

Developed and Maintain by Jonathan Ben Hur Freelancer