Skip to content

Commit 21259c2

Browse files
pfrenssenpaul-m
authored andcommitted
Issue #2774601 by pfrenssen: Ajax Form Example does not submit the value for 'color' added by ajax callback
1 parent acf7581 commit 21259c2

File tree

1 file changed

+88
-62
lines changed

1 file changed

+88
-62
lines changed

fapi_example/src/Form/AjaxDemo.php

Lines changed: 88 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,101 +15,127 @@
1515
* @see \Drupal\Core\Form\ConfigFormBase
1616
*/
1717
class AjaxDemo extends DemoBase {
18-
/*
19-
* Possible colors to choose from.
20-
* Used by colorCallback to determine which colors to include in the
21-
* select element.
22-
*/
2318

24-
private $colors = [
25-
'warm' => [
26-
'red' => 'Red',
27-
'orange' => 'Orange',
28-
'yellow' => 'Yellow',
29-
],
30-
'cool' => [
31-
'blue' => 'Blue',
32-
'purple' => 'Purple',
33-
'green' => 'Green',
34-
],
35-
];
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
public function getFormId() {
23+
return 'fapi_example_ajax_demo';
24+
}
3625

3726
/**
3827
* {@inheritdoc}
3928
*/
4029
public function buildForm(array $form, FormStateInterface $form_state) {
41-
42-
/*
43-
* The #ajax attribute used in the temperature input element defines an ajax
44-
* callback that will invoke the colorCallback method on this form object.
45-
* Whenever the temperature element changes, it will invoke this callback
46-
* and replace the contents of the color_wrapper container with the results
47-
* of this method call.
48-
*/
30+
// The #ajax attribute used in the temperature input element defines an ajax
31+
// callback that will invoke the 'updateColor' method on this form object.
32+
// Whenever the temperature element changes, it will invoke this callback
33+
// and replace the contents of the 'color_wrapper' container with the
34+
// results of this method call.
4935
$form['temperature'] = [
5036
'#title' => $this->t('Temperature'),
5137
'#type' => 'select',
52-
'#options' => ['warm' => 'Warm', 'cool' => 'Cool'],
53-
'#empty_option' => $this->t('-select'),
38+
'#options' => $this->getColorTemperatures(),
39+
'#empty_option' => $this->t('- Select a color temperature -'),
5440
'#ajax' => [
55-
// Could also use [ $this, 'colorCallback'].
56-
'callback' => '::colorCallback',
41+
// Could also use [get_class($this), 'updateColor'].
42+
'callback' => '::updateColor',
5743
'wrapper' => 'color-wrapper',
5844
],
5945
];
6046

61-
// Disable caching on this form.
62-
$form_state->setCached(FALSE);
63-
64-
$form['actions'] = [
65-
'#type' => 'actions',
66-
];
67-
68-
// Add a submit button that handles the submission of the form.
69-
$form['actions']['submit'] = [
70-
'#type' => 'submit',
71-
'#value' => $this->t('Submit'),
72-
];
73-
47+
// Add a wrapper that can be replaced with new HTML by the ajax callback.
48+
// This is given the ID that was passed to the ajax callback in the '#ajax'
49+
// element above.
7450
$form['color_wrapper'] = [
7551
'#type' => 'container',
7652
'#attributes' => ['id' => 'color-wrapper'],
7753
];
7854

55+
// Add a color element to the color_wrapper container using the value
56+
// from temperature to determine which colors to include in the select
57+
// element.
58+
$temperature = $form_state->getValue('temperature');
59+
if (!empty($temperature)) {
60+
$form['color_wrapper']['color'] = [
61+
'#type' => 'select',
62+
'#title' => $this->t('Color'),
63+
'#options' => $this->getColorsByTemperature($temperature),
64+
];
65+
}
66+
67+
// Add a submit button that handles the submission of the form.
68+
$form['actions'] = [
69+
'#type' => 'actions',
70+
'submit' => [
71+
'#type' => 'submit',
72+
'#value' => $this->t('Submit'),
73+
],
74+
];
75+
7976
return $form;
8077
}
8178

8279
/**
83-
* {@inheritdoc}
80+
* Ajax callback for the color dropdown.
8481
*/
85-
public function getFormId() {
86-
return 'fapi_example_ajax_demo';
82+
public function updateColor(array $form, FormStateInterface $form_state) {
83+
return $form['color_wrapper'];
8784
}
8885

8986
/**
90-
* Implements callback for Ajax event on color selection.
87+
* Returns colors that correspond with the given temperature.
9188
*
92-
* @param array $form
93-
* From render array.
94-
* @param \Drupal\Core\Form\FormStateInterface $form_state
95-
* Current state of form.
89+
* @param string $temperature
90+
* The color temperature for which to return a list of colors. Can be either
91+
* 'warm' or 'cool'.
9692
*
9793
* @return array
98-
* Color selection section of the form.
94+
* An associative array of colors that correspond to the given color
95+
* temperature, suitable to use as form options.
9996
*/
100-
public function colorCallback(array &$form, FormStateInterface $form_state) {
101-
$temperature = $form_state->getValue('temperature');
97+
protected function getColorsByTemperature($temperature) {
98+
return $this->getColors()[$temperature]['colors'];
99+
}
102100

103-
// Add a color element to the color_wrapper container using the value
104-
// from temperature to determine which colors to include in the select
105-
// element.
106-
$form['color_wrapper']['color'] = [
107-
'#type' => 'select',
108-
'#title' => $this->t('Color'),
109-
'#options' => $this->colors[$temperature],
110-
];
101+
/**
102+
* Returns a list of color temperatures.
103+
*
104+
* @return array
105+
* An associative array of color temperatures, suitable to use as form
106+
* options.
107+
*/
108+
protected function getColorTemperatures() {
109+
return array_map(function ($color_data) {
110+
return $color_data['name'];
111+
}, $this->getColors());
112+
}
111113

112-
return $form['color_wrapper'];
114+
/**
115+
* Returns an array of colors grouped by color temperature.
116+
*
117+
* @return array
118+
* An associative array of color data, keyed by color temperature.
119+
*/
120+
protected function getColors() {
121+
return [
122+
'warm' => [
123+
'name' => $this->t('Warm'),
124+
'colors' => [
125+
'red' => $this->t('Red'),
126+
'orange' => $this->t('Orange'),
127+
'yellow' => $this->t('Yellow'),
128+
],
129+
],
130+
'cool' => [
131+
'name' => $this->t('Cool'),
132+
'colors' => [
133+
'blue' => $this->t('Blue'),
134+
'purple' => $this->t('Purple'),
135+
'green' => $this->t('Green'),
136+
],
137+
],
138+
];
113139
}
114140

115141
}

0 commit comments

Comments
 (0)