Problem/Motivation
It was discovered in
#2577219: Single item configuration export form config_name does not have "- Select -" as it's first option →
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
Code review and validate the used approach.
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
None