Problem/Motivation
It was discovered in #2577219: Select's #empty_option gets removed on ajax callback that select element adds #empty_option
in Select::processSelect
. However, if a select element is updated (re-rendered?) on an ajax callback, the #empty_option
gets removed.
Steps to reproduce
Create a form with the following in buildForm
$form['ajax_parent_select'] = [
'#title' => $this->t('Parent select with Ajax callback'),
'#type' => 'select',
'#options' => ['one' => 'One', 'two' => 'Two'],
'#default_value' => 'one',
'#ajax' => [
'callback' => '::ajaxCallback',
'wrapper' => 'child-wrapper',
],
];
$form['ajax_child_select'] = [
'#title' => $this->t('Child select'),
'#type' => 'select',
'#options' => ['three' => 'Three'],
'#empty_option' => $this->t('- Select -'),
'#prefix' => '<div id="child-wrapper">',
'#suffix' => '</div>',
];
Where ajaxCallback
looks something like this
public function ajaxCallback($form, FormStateInterface $form_state) {
$options = [
'one' => ['three' => 'Three'],
'two' => ['four' => 'Four'],
];
$form['ajax_child_select']['#options'] = $options[$form_state->getValue('ajax_parent_select')];
return $form['ajax_child_select'];
}
When ajaxCallback
fires, it removes #empty_option
during re-rendering of ajax_child_select
This has been demonstrated here
Proposed resolution
Add #empty_option
in a #pre_render
callback
Remaining tasks
Provide patch to fix the issue.
Write a test to prevent regression.
Code review and validate the used approach.
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
None