Рейтинг:0

Как динамически (AJAX) отображать радио в форме API?

флаг au

Ожидается, что форма, подобная следующей, будет отображать дополнительные поля, когда пользователь выберет «Да» в переключателе «Показать больше». Когда показано, в разделе «Дополнительно» есть текстовое поле «Имя» и набор радио «Пол».

Но это никогда не работает так, как ожидалось. Метка «Пол» будет там, но переключатели никогда не отображаются. Я знаю, что изменение «Пол» на радио будет работать, но по какой-то причине мне нужно использовать несколько переключателей. Есть ли способ заставить это работать?

<?php

пространство имен Drupal\mymodule\Form;

используйте Drupal\Core\Form\FormBase;

класс DonationPrepareForm расширяет FormBase {

  /**
   * {@inheritdoc}
   */
  публичная функция getFormId() {
    вернуть 'my_form';
  }

  /**
   * {@inheritdoc}
   */
  публичная функция buildForm(
    массив $ форма,
    FormStateИнтерфейс $form_state
  ) {
    $form['show_more'] = [
      '#type' => 'радио',
      '#title' => 'Показать больше',
      '#варианты' => [
        'Д' => 'Да',
        'Н' => 'Нет',
      ],
      '#ajax' => [
        'обратный вызов' => '::ajaxBuildForm',
        'обертка' => 'редактировать больше обертки',
        'прогресс' => [
          'тип' => 'пульсирующий',
          'сообщение' => $this->t('Загрузка...'),
        ],
      ],
    ];
    $ форма ['больше'] = [
      '#type' => 'контейнер',
      '#prefix' => '<div id="edit-more-wrapper">',
      '#суффикс' => '</div>',
    ];

    вернуть $ форму;
  }

  публичная функция ajaxBuildForm (массив и форма $, FormStateInterface $ form_state)
  {
    если ($form_state->getValue('show_more') === 'Y') {
      $form['больше']['имя'] = [
        '#тип' => 'текстовое поле',
        '#title' => 'Имя',
        '#required' => ИСТИНА,
      ];
      $form['больше']['пол'] = [
        '#type' => 'радио',
        '#title' => 'Пол',
        '#варианты' => [
          'М' => 'Мужской',
          'Ж' => 'Женщина',
        ],
        '#required' => ИСТИНА,
      ];
    }
    возврат $form['больше'];
  }
}

Тот же вопрос распространяется и на другие составные элементы формы (например,Флажки). Есть ли способ заставить AJAX работать на них?

Рейтинг:2
флаг cn

На самом деле значительно проще использовать свойство элемента формы #states, чтобы сделать элемент видимым, невидимым, включенным, отключенным, обязательным или ... вместо использования ajax

Такой код выполнит эту работу:

<?php

пространство имен Drupal\mymodule\Form;

используйте Drupal\Core\Form\FormBase;

класс DonationPrepareForm расширяет FormBase {

  /**
   * {@inheritdoc}
   */
  публичная функция getFormId() {
    вернуть 'my_form';
  }

  /**
   * {@inheritdoc}
   */
  публичная функция buildForm(
    массив $ форма,
    FormStateИнтерфейс $form_state
  ) {
    $form['show_more'] = [
      '#type' => 'радио',
      '#title' => 'Показать больше',
      '#варианты' => [
        'Д' => 'Да',
        'Н' => 'Нет',
      ],
    ];


    $form['больше']['имя'] = [
      '#тип' => 'текстовое поле',
      '#title' => 'Имя',
      '#states' => массив(
        'видимый' => массив (
          ':input[name="show_more"]' => массив('value' => 'Y'),
        ),
        'требуется' => массив (
          ':input[name="show_more"]' => массив('value' => 'Y'),
        )
      ),
    ];
    $form['больше']['пол'] = [
      '#type' => 'радио',
      '#title' => 'Пол',
      '#варианты' => [
        'М' => 'Мужской',
        'Ж' => 'Женщина',
      ],
      '#states' => массив(
        'видимый' => массив (
          ':input[name="show_more"]' => массив('value' => 'Y'),
        ),
        'требуется' => массив (
          ':input[name="show_more"]' => массив('value' => 'Y'),
        )
      ),
    ];

    вернуть $ форму;
  }

}

флаг au
Это не работает для моего случая, потому что я бы хотел, чтобы появившиеся поля были обязательными полями.
флаг in
Что именно не работает? Требуемое состояние также зависит от ввода в ответе?
Рейтинг:1
флаг cn

Переместите построение формы в buildForm(). Вы не можете создавать элементы формы в обратном вызове Ajax (я также переименовал метод обратного вызова, чтобы было понятно):

<?php

пространство имен Drupal\mymodule\Form;

используйте Drupal\Core\Form\FormBase;

класс DonationPrepareForm расширяет FormBase {

  /**
   * {@inheritdoc}
   */
  публичная функция getFormId() {
    вернуть 'my_form';
  }

  /**
   * {@inheritdoc}
   */
  общедоступная функция buildForm (массив $ form, FormStateInterface $ form_state) {
     $form['show_more'] = [
      '#type' => 'радио',
      '#title' => 'Показать больше',
      '#варианты' => [
        'Д' => 'Да',
        'Н' => 'Нет',
      ],
      '#ajax' => [
        'обратный вызов' => '::ajaxCallback',
        'обертка' => 'редактировать больше обертки',
        'прогресс' => [
          'тип' => 'пульсирующий',
          'сообщение' => $this->t('Загрузка...'),
        ],
      ],
    ];
    $ форма ['больше'] = [
      '#type' => 'контейнер',
      '#prefix' => '<div id="edit-more-wrapper">',
      '#суффикс' => '</div>',
    ];

    если ($form_state->getValue('show_more') === 'Y') {
      $form['больше']['имя'] = [
        '#тип' => 'текстовое поле',
        '#title' => 'Имя',
        '#required' => ИСТИНА,
      ];
      $form['больше']['пол'] = [
        '#type' => 'радио',
        '#title' => 'Пол',
        '#варианты' => [
          'М' => 'Мужской',
          'Ж' => 'Женщина',
        ],
        '#required' => ИСТИНА,
      ];
    }

    вернуть $ форму;
  }

  публичная функция ajaxCallback (массив и $ форма, FormStateInterface $ form_state) {
    возврат $form['больше'];
  }
}
флаг au
Большое спасибо. Оно работает!

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.