Я пытаюсь позволить пользователю динамически выбирать количество полей на основе раскрывающегося списка с помощью вызова ajax, но я не могу получить вызов ajax, чтобы впоследствии перестроить форму.
<?php
class AJAXexample extends BlockBase {
public function blockForm($form, FormStateInterface $form_state) {
if (empty($form_state->getValue('number'))) {
$form_state->setValue('number', 3);
}
$form['columnNum'] = [
'#title' => t('Number of Columns'),
'#type' => 'select',
'#options' => [
1 => '1',
2 => '2',
3 => '3',
4 => '4',
],
'#default_value' => $this->configuration['columnNum'],
'#empty_option' => t('-select-'),
'#ajax' => [
'callback' => [$this, 'columnCallback'],
],
];
for ($i = 0; $i < $form_state->getValue('number'); $i += 1) {
$form['column'][$i] = [
$i => [
'#type' => 'details',
'#title' => t('Column '.$numTitle),
'#open' => FALSE,
'columnTitle' => [
'#type' => 'textfield',
'#title' => t('Column Title'),
'#value' => $config[0]['columnTitle'],
],
],
];
return $form;
}
public function columnCallback(array &$form, FormStateInterface $form_state) {
$form_state->setValue('number', 10);
$form_state->setRebuild(true);
return $form;
}
}
Количество текстовых полей зависит от переменной form_state 'number'. Функция обратного вызова columnCallback изменяет переменную form_state на 10 и вызывается при изменении поля формы columnNum. Однако форма не перестраивается с новым количеством полей, хотя $ form_state-> setRebuild (); называется. Есть ли способ получить форму для восстановления после вызова AJAX?
ПРИМЕЧАНИЕ. Я уже пробовал такие методы, как замена или добавление элементов формы внутри фактического вызова ajax, но когда это происходит, ни один из входных данных в замененные поля не передается в $ form_state.
ОБНОВЛЕНИЕ: после попытки решения 4k4 я получаю ошибку
Recoverable fatal error: Argument 1 passed to Drupal\Core\Render\MainContent\AjaxRenderer::renderResponse() must be of the type array, null given, called in /Library/WebServer/Documents/aaep/web/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php on line 89 and defined in Drupal\Core\Render\MainContent\AjaxRenderer->renderResponse() (line 45 of /Library/WebServer/Documents/aaep/web/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php).
Предполагается, что ошибка возникает из-за того, что $ form ['column'] возвращает значение null, несмотря на то, что оно было создано в качестве контейнера в функции blockForm. Я пытался вызвать обратный вызов другими способами, такими как
'#ajax' => [
'callback' => '::columnCallback',
]
и
'#ajax' => [
'callback' => [$this, '\Drupal\my_examples\Plugin\Block\AJAXexample::columnCallback'],
]
Но я получаю ту же ошибку. Любопытно, что когда я изменяю функцию обратного вызова для возврата всей формы $ вместо просто $ form ['column'], она повторяет форму (копия формы появляется под текущей формой) и все еще без надлежащего числа столбцов.
Ответы:
Первая проблема - обработать значение для номера столбца. При первой сборке получить его из конфигурации, при повторной сборке получить из пользовательского ввода и вставить его
$columnNum
.Второй - решить, какая часть формы изменяется в AJAX, и поместить это в контейнер div с идентификатором
columns-wrapper
.В обратном вызове нам нужно только вернуть ajax-оболочку.
Drupal перестраивает форму при каждом запросе ajax и помещает ее в параметр
$form
обратного вызова. Нет смысла пытаться восстановить его снова.источник
return $form['column']
ноль, потому что возвращаемое значение не проверяетсяrenderResponse()
. Может все еще быть проблема со списком параметров обратного вызова, потому что мы поместили по крайней мере контейнер в этот ключ формы, и это предотвратит эту ошибку.Я предполагаю, что вы пропустили
wrapper
метод в вашем'#ajax'
(рядом сcallback
), который состоит изid
атрибута HTML области, где должен быть размещен контент, возвращаемый обратным вызовом. Смотрите: Ajax API . Затем вы должны убедиться, что такой контейнерid
существует.Пример кода (упрощенно):
Для полного примера кода смотрите: Как добавить больше опций для радиостанций типа Ajax в Drupal 8 .
источник