function DependentDropdown::buildForm
Same name in other branches
- 8.x-1.x ajax_example/src/Form/DependentDropdown.php \Drupal\ajax_example\Form\DependentDropdown::buildForm()
- 4.0.x modules/ajax_example/src/Form/DependentDropdown.php \Drupal\ajax_example\Form\DependentDropdown::buildForm()
The $nojs parameter is specified as a path parameter on the route.
Overrides FormInterface::buildForm
See also
File
-
modules/
ajax_example/ src/ Form/ DependentDropdown.php, line 28
Class
- DependentDropdown
- Re-populate a dropdown based on form state.
Namespace
Drupal\ajax_example\FormCode
public function buildForm(array $form, FormStateInterface $form_state, $nojs = NULL) {
// Add our CSS and tiny JS to hide things when they should be hidden.
$form['#attached']['library'][] = 'ajax_example/ajax_example.library';
// Explanatory text with helpful links.
$form['info'] = [
'#markup' => $this->t('<p>Like other examples in this module, this form has a path that
can be modified with /nojs to simulate its behavior without JavaScript.
</p><ul>
<li>@try_it_without_ajax</li>
<li>@try_it_with_ajax</li>
</ul>', [
'@try_it_without_ajax' => Link::createFromRoute($this->t('Try it without AJAX'), 'ajax_example.dependent_dropdown', [
'nojs' => 'nojs',
])
->toString(),
'@try_it_with_ajax' => Link::createFromRoute($this->t('Try it with AJAX'), 'ajax_example.dependent_dropdown')
->toString(),
]),
];
// Our first dropdown lets us select a family of instruments: String,
// Woodwind, Brass, or Percussion.
$instrument_family_options = static::getFirstDropdownOptions();
// When the AJAX request occurs, this form will be build in order to process
// form state before the AJAX callback is called. We can use this
// opportunity to populate the form as we wish based on the changes to the
// form that caused the AJAX request. If the user caused the AJAX request,
// then it would have been setting a value for instrument_family_options.
// So if there's a value in that dropdown before we build it here, we grab
// it's value to help us build the specific instrument dropdown. Otherwise
// we can just use the value of the first item as the default value.
if (empty($form_state->getValue('instrument_family_dropdown'))) {
// Use a default value.
$selected_family = key($instrument_family_options);
}
else {
// Get the value if it already exists.
$selected_family = $form_state->getValue('instrument_family_dropdown');
}
$form['instrument_family_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this->t('Choose an instrument family'),
];
$form['instrument_family_fieldset']['instrument_family_dropdown'] = [
'#type' => 'select',
'#title' => $this->t('Instrument Type'),
'#options' => $instrument_family_options,
'#default_value' => $selected_family,
// Bind an ajax callback to the change event (which is the default for the
// select form type) of the first dropdown. It will replace the second
// dropdown when rebuilt.
'#ajax' => [
// When 'event' occurs, Drupal will perform an ajax request in the
// background. Usually the default value is sufficient (eg. change for
// select elements), but valid values include any jQuery event,
// most notably 'mousedown', 'blur', and 'submit'.
'callback' => '::instrumentDropdownCallback',
'wrapper' => 'instrument-fieldset-container',
],
];
// Since we don't know if the user has js or not, we always need to output
// this element, then hide it with with css if javascript is enabled.
$form['instrument_family_fieldset']['choose_family'] = [
'#type' => 'submit',
'#value' => $this->t('Choose'),
'#attributes' => [
'class' => [
'ajax-example-hide',
'ajax-example-inline',
],
],
];
// We are using the path parameter $nojs to signal when to simulate the
// the user turning off JavaScript. We'll remove all the AJAX elements. This
// is not required, and is here so that we can demonstrate a graceful
// fallback without having to turn off JavaScript.
if ($nojs == 'nojs') {
// Removing the #ajax element tells the system not to use AJAX.
unset($form['instrument_family_fieldset']['instrument_family_dropdown']['#ajax']);
// Removing the ajax-example-hide class from the Choose button ensures
// that our JavaScript won't hide it.
unset($form['instrument_family_fieldset']['choose_family']['#attributes']);
}
// Since we're managing state for this whole fieldset (both the dropdown
// and enabling the Submit button), we want to replace the whole thing
// on AJAX requests. That's why we put it in this container.
$form['instrument_fieldset_container'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'instrument-fieldset-container',
],
];
// Build the instrument field set.
$form['instrument_fieldset_container']['instrument_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this->t('Choose an instrument'),
];
$form['instrument_fieldset_container']['instrument_fieldset']['instrument_dropdown'] = [
'#type' => 'select',
'#title' => $instrument_family_options[$selected_family] . ' ' . $this->t('Instruments'),
// When the form is rebuilt during ajax processing, the $selected_family
// variable will now have the new value and so the options will change.
'#options' => static::getSecondDropdownOptions($selected_family),
'#default_value' => !empty($form_state->getValue('instrument_dropdown')) ? $form_state->getValue('instrument_dropdown') : '',
];
$form['instrument_fieldset_container']['instrument_fieldset']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
// We might normally use #state to disable the instrument fields based on
// the instrument family fields. But since the premise is that we don't have
// JavaScript running, #state won't work either. We have to set up the state
// of the instrument fieldset here, based on the selected instrument family.
if ($selected_family == 'none') {
$form['instrument_fieldset_container']['instrument_fieldset']['instrument_dropdown']['#title'] = $this->t('You must choose an instrument family.');
$form['instrument_fieldset_container']['instrument_fieldset']['instrument_dropdown']['#disabled'] = TRUE;
$form['instrument_fieldset_container']['instrument_fieldset']['submit']['#disabled'] = TRUE;
}
else {
$form['instrument_fieldset_container']['instrument_fieldset']['instrument_dropdown']['#disabled'] = FALSE;
$form['instrument_fieldset_container']['instrument_fieldset']['submit']['#disabled'] = FALSE;
}
return $form;
}