diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php index d00547535b1fa21c3bfff81fd6ca0114902f6be4..e238ff59693acd8e2bc023f6efb5a5ed43b983eb 100644 --- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php +++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php @@ -45,6 +45,7 @@ public function getInfo() { ], '#process' => [ [$class, 'processDatetime'], + [$class, 'processAjaxForm'], [$class, 'processGroup'], ], '#pre_render' => [ @@ -311,6 +312,25 @@ public static function processDatetime(&$element, FormStateInterface $form_state return $element; } + /** + * {@inheritdoc} + */ + public static function processAjaxForm(&$element, FormStateInterface $form_state, &$complete_form) { + $element = parent::processAjaxForm($element, $form_state, $complete_form); + + // Copy the #ajax settings to the child elements. + if (isset($element['#ajax'])) { + if (isset($element['date'])) { + $element['date']['#ajax'] = $element['#ajax']; + } + if (isset($element['time'])) { + $element['time']['#ajax'] = $element['#ajax']; + } + } + + return $element; + } + /** * Validation callback for a datetime element. * diff --git a/core/lib/Drupal/Core/Render/Element/Date.php b/core/lib/Drupal/Core/Render/Element/Date.php index 11e15d8443bfbeeff63a8cc90b23dbeee3a9e3c6..735b1d5ce5f4a7de829b72fea6ad83385344a0cf 100644 --- a/core/lib/Drupal/Core/Render/Element/Date.php +++ b/core/lib/Drupal/Core/Render/Element/Date.php @@ -33,7 +33,10 @@ public function getInfo() { return [ '#input' => TRUE, '#theme' => 'input__date', - '#process' => [[$class, 'processDate']], + '#process' => [ + [$class, 'processAjaxForm'], + [$class, 'processDate'], + ], '#pre_render' => [[$class, 'preRenderDate']], '#theme_wrappers' => ['form_element'], '#attributes' => ['type' => 'date'], diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php index 243a9af7671063ac347db6881e50bee110e6791c..46c6f297e3c8e4cd71859ab7cf06e1d983f6ee6a 100644 --- a/core/lib/Drupal/Core/Render/Element/RenderElement.php +++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php @@ -269,6 +269,7 @@ public static function preRenderAjaxForm($element) { $element['#attributes']['data-disable-refocus'] = "true"; } + // Add a reasonable default event handler if none was specified. if (isset($element['#ajax']) && !isset($element['#ajax']['event'])) { switch ($element['#type']) { @@ -308,6 +309,7 @@ public static function preRenderAjaxForm($element) { case 'radio': case 'checkbox': case 'select': + case 'date': $element['#ajax']['event'] = 'change'; break; diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml index 627140841712daddabf745e7bf4764a4acc32f1d..57801a3e2df2f2f9479f98817f97aeebcfca9a97 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml +++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml @@ -38,3 +38,11 @@ ajax_forms_test.image_button_form: requirements: _access: 'TRUE' +ajax_forms_test.ajax_element_form: + path: '/ajax_forms_test_ajax_element_form' + defaults: + _title: 'AJAX forms elements test' + _form: '\Drupal\ajax_forms_test\Form\AjaxFormsTestAjaxElementsForm' + requirements: + _access: 'TRUE' + diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php b/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php index 06c4b0bb0d063e81243095c991cbc9ba4286f1c2..0c91513f857370b2ae00b6f3c863f0609d39ecd4 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php @@ -22,6 +22,18 @@ public function selectCallback($form, FormStateInterface $form_state) { return $response; } + /** + * Ajax callback triggered by datetime. + */ + public function datetimeCallback($form, FormStateInterface $form_state) { + $datetime = $form_state->getValue('datetime')['date'] . ' ' . $form_state->getValue('datetime')['time']; + + $response = new AjaxResponse(); + $response->addCommand(new HtmlCommand('#ajax_datetime_value', $datetime)); + $response->addCommand(new DataCommand('#ajax_datetime_value', 'form_state_value_datetime', $datetime)); + return $response; + } + /** * Ajax callback triggered by checkbox. */ diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php new file mode 100644 index 0000000000000000000000000000000000000000..3a1e746fa0d4b272907a9e71420f4f97e0b032f4 --- /dev/null +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php @@ -0,0 +1,48 @@ + 'datetime', + '#ajax' => [ + 'callback' => [$callback_object, 'datetimeCallback'], + 'wrapper' => 'ajax_datetime_value', + ], + ]; + + $form['datetime_result'] = [ + '#type' => 'markup', + '#markup' => '
No date selected.
', + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) {} + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c45c5907e5e5a40fa99bde3e312ff3a905f55305 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php @@ -0,0 +1,36 @@ +drupalGet('ajax_forms_test_ajax_element_form'); + $this->assertSession()->responseContains('No date selected.'); + $this->getSession()->getPage()->fillField('edit-datetime-date', '2016-01-01'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->assertSession()->responseNotContains('No date selected.'); + $this->assertSession()->responseContains('2016-01-01'); + $this->getSession()->getPage()->fillField('edit-datetime-time', '12:00:00'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->assertSession()->responseContains('2016-01-01 12:00:00'); + } + +}