I'm attempting to allow the user to dynamically choose a number of fields based on a dropdown box using an ajax call, but I can't seem to get the ajax call to rebuild the form afterwards.
<?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;
}
}
The number of textfields is based on the form_state variable 'number'. The callback columnCallback changes the form_state variable to 10, and is fired when the 'columnNum' form field is changed. However the form isn't rebuilt with the new number of fields even though $form_state->setRebuild(); is called. Is there a way to get the form to rebuild after an ajax call?
NOTE: I have already tried techniques such as replacing or appending the items of the form inside of the actual ajax call but when that happens none of the input into the replaced fields get passed to $form_state.
UPDATE: After attempting 4k4's solution I receive an error
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).
The belief is that the error occurs because $form['column'] is returning null despite being created as a container in the blockForm function. I've attempted calling the callback in other ways like
'#ajax' => [
'callback' => '::columnCallback',
]
and
'#ajax' => [
'callback' => [$this, '\Drupal\my_examples\Plugin\Block\AJAXexample::columnCallback'],
]
But I receive the same error. Curiously, when I change the callback to return the entire $form instead of just $form['column'] it repeats the form (a copy of the form appears below the current form) and still without the proper number of columns.