AJAX commands documentation is misleading when working with render arrays

Created on 30 June 2016, over 8 years ago
Updated 29 March 2023, over 1 year ago

The class documentation of InsertCommand and all commands extending it only state that they accept HTML as input content, while InsertCommand::construct() correctly states that it accepts a render array or an HTML string. But passing HTML creates problems with AJAX forms.

The problem is that the documentation erroneously push developers to convert render arrays into HTML, with \Drupal::service('renderer')->render(), before passing the output to the AJAX command. It often happens with Form API elements. Any element which had '#ajax' properties set will lose them if they are rendered as HTML before being passed to one of these AJAX commands.

If instead of passing HTML, the render array was passed directly to one of these AJAX commands, the '#ajax' properties will work as expected.

This kind of issue can be hard to debug since the documentation seems to indicate we have to use HTML with these AJAX commands.

Affected:

  • AfterCommand
  • AppendCommand
  • BeforeCommand
  • HtmlCommand
  • InsertCommand
  • PreprendCommand
  • ReplaceCommand
  • Maybe OpenDialogCommand which also uses CommandWithAttachedAssetsTrait

Proposed fix: update the class documentation of these commands to indicate they accept render arrays. It could also help to mention best practices about handling render arrays with AJAX commands on https://api.drupal.org/api/drupal/core!core.api.php/group/ajax/

Original issue content:

I am trying to create an Ajax form with three dependent selects, following the Ajax guide provided by Examples module https://api.drupal.org/api/examples/fapi_example!src!Form!AjaxDemo.php/c...

The first two select works perfectly, but the render of third doesn't work, the select in return by a callback function.

Let me show you the fist select code

    $form['state'] = array(
      '#type' => 'select',
      '#title' => $this->t('State'),
      '#description' => $this->t('Please select your favorite state'),
      '#options' => $this->states,
      '#size' => 1,
      '#empty_option' => $this->t('-select-'),
      '#ajax' => array(
          'callback' => '::updateCities',
          'wrapper' => 'city-wrapper',
          'event' => 'change',
          'progress' => array(
              'type' => 'throbber',
              'message' => "searching",
          ),
      )
    );

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

Below the callback function

function updateCities($form, FormStateInterface $form_state) {
    $state = $form_state->getValue('state');
    if(!empty($this->cities[$state])) {
      $form['city_wrapper']['city'] = array(
          '#attributes' => ['id' => 'city-wrapper'],
          '#type' => 'select',
          '#title' => $this->t('City'),
          '#description' => $this->t('Please select your favorite city'),
          '#size' => 1,
          '#empty_option' => $this->t('-select-'),
          '#options' => $this->cities[$state],
          '#ajax' => array(
              'callback' => '::updateStudies',
              'wrapper' => 'study-wrapper',
              'event' => 'change',
              'progress' => array(
                  'type' => 'throbber',
                  'message' => "searching",
              ),
          )
      );
    }

    $response = new AjaxResponse();
    $response->addCommand(new InsertCommand('#taxonomy-term-data-form', $form['city_wrapper']['city']));
    return $response;
  }

The second select is render properly but without ajax effect to render the third select, I tried returning the FAPI element with the same result.

Here an image of first two select elements working.

In addition, the second select don't allow to be render without selection the first element is immediately selected, I don't know if this a separate issue.

πŸ› Bug report
Status

Fixed

Version

10.1 ✨

Component
AjaxΒ  β†’

Last updated 1 day ago

Created by

πŸ‡¦πŸ‡ΊAustralia -enzo-

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024