Usiłuję umożliwić użytkownikowi dynamiczny wybór liczby pól na podstawie listy rozwijanej za pomocą wywołania ajax, ale nie mogę uzyskać połączenia wywoływanego przez ajax, aby później odbudować formularz.
<?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;
}
}
Liczba pól tekstowych jest oparta na zmiennej „liczba” form_state. Wywołanie zwrotne columnCallback zmienia zmienną form_state na 10 i jest uruchamiane po zmianie pola formularza „columnNum”. Jednak formularz nie jest przebudowywany z nową liczbą pól, mimo że $ form_state-> setRebuild (); nazywa się. Czy istnieje sposób na przebudowanie formularza po wywołaniu ajax?
UWAGA: Próbowałem już takich technik, jak zamiana lub dopisywanie elementów formularza wewnątrz rzeczywistego wywołania ajax, ale kiedy tak się dzieje, żadne dane wejściowe do zastąpionych pól nie są przekazywane do $ form_state.
AKTUALIZACJA: Po próbie rozwiązania 4k4 pojawia się błąd
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).
Uważa się, że błąd występuje, ponieważ $ form ['column'] zwraca wartość null, mimo że został utworzony jako kontener w funkcji blockForm. Próbowałem oddzwonić na inne sposoby
'#ajax' => [
'callback' => '::columnCallback',
]
i
'#ajax' => [
'callback' => [$this, '\Drupal\my_examples\Plugin\Block\AJAXexample::columnCallback'],
]
Ale otrzymuję ten sam błąd. Co ciekawe, kiedy zmieniam wywołanie zwrotne, aby zwracać cały formularz $ zamiast tylko $ form [„kolumna”], powtarza formularz (kopia formularza pojawia się pod bieżącym formularzem) i nadal bez odpowiedniej liczby kolumn.
Odpowiedzi:
Pierwszym problemem jest obsługa wartości numeru kolumny. Przy pierwszej kompilacji pobierz go z konfiguracji, przy przebudowie pobierz go z danych wejściowych użytkownika i włóż
$columnNum
.Drugim jest decyzja, która część formularza zmieni się w AJAX i umieść to w pojemniku div z identyfikatorem
columns-wrapper
.W wywołaniu zwrotnym musimy tylko zwrócić opakowanie ajax.
Drupal odbudowuje formularz przy każdym żądaniu ajax i umieszcza go w parametrze
$form
wywołania zwrotnego. Nie ma sensu próbować go odbudowywać.źródło
return $form['column']
jest pusty, ponieważ zwracana wartość jest odznaczanarenderResponse()
. Nadal może występować problem z listą parametrów wywołania zwrotnego, ponieważ w tym formularzu umieszczamy co najmniej kontener, co zapobiegnie temu błędowi.Chyba brakuje Ci
wrapper
metody w'#ajax'
(obokcallback
), która zawieraid
atrybut HTML obszaru, w którym powinna zostać umieszczona treść zwrócona przez wywołanie zwrotne. Zobacz: Ajax API . Następnie upewnij się, że taki kontenerid
istnieje.Przykład kodu (uproszczony):
Aby uzyskać pełny przykład kodu, zobacz: Jak dodać więcej opcji dla radiotelefonów, użyj Ajax w Drupal 8 .
źródło