summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2017-09-26 12:13:58 (GMT)
committerNathaniel Catchpole2017-09-26 12:13:58 (GMT)
commit57762d192d623955d58fb8b17769d98a04d1309e (patch)
treebfa8af7899aeb1b668d9ca00b11461124ff2755c
parente64d7536a67594e35c5d89ef342da41996061b83 (diff)
Issue #2783615 by k4v, Dom., dawehner: Datetime FAPI element type do not allow AJAX via #ajax API
-rw-r--r--core/lib/Drupal/Core/Datetime/Element/Datetime.php20
-rw-r--r--core/lib/Drupal/Core/Render/Element/Date.php5
-rw-r--r--core/lib/Drupal/Core/Render/Element/RenderElement.php2
-rw-r--r--core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml8
-rw-r--r--core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php12
-rw-r--r--core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php48
-rw-r--r--core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php36
7 files changed, 130 insertions, 1 deletions
diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php
index d005475..e238ff5 100644
--- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php
+++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php
@@ -45,6 +45,7 @@ class Datetime extends DateElementBase {
],
'#process' => [
[$class, 'processDatetime'],
+ [$class, 'processAjaxForm'],
[$class, 'processGroup'],
],
'#pre_render' => [
@@ -312,6 +313,25 @@ class Datetime extends DateElementBase {
}
/**
+ * {@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.
*
* If the date is valid, the date object created from the user input is set in
diff --git a/core/lib/Drupal/Core/Render/Element/Date.php b/core/lib/Drupal/Core/Render/Element/Date.php
index 11e15d8..735b1d5 100644
--- a/core/lib/Drupal/Core/Render/Element/Date.php
+++ b/core/lib/Drupal/Core/Render/Element/Date.php
@@ -33,7 +33,10 @@ class Date extends FormElement {
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 243a9af..46c6f29 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -269,6 +269,7 @@ abstract class RenderElement extends PluginBase implements ElementInterface {
$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 @@ abstract class RenderElement extends PluginBase implements ElementInterface {
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 6271408..57801a3 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 06c4b0b..0c91513 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
@@ -23,6 +23,18 @@ class Callbacks {
}
/**
+ * 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.
*/
public function checkboxCallback($form, FormStateInterface $form_state) {
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 0000000..3a1e746
--- /dev/null
+++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Drupal\ajax_forms_test\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\ajax_forms_test\Callbacks;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Form builder: Builds a form that has each FAPI elements triggering a simple
+ * Ajax callback.
+ */
+class AjaxFormsTestAjaxElementsForm extends FormBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'ajax_forms_test_ajax_elements_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, FormStateInterface $form_state) {
+ $callback_object = new Callbacks();
+ $form['datetime'] = [
+ '#type' => 'datetime',
+ '#ajax' => [
+ 'callback' => [$callback_object, 'datetimeCallback'],
+ 'wrapper' => 'ajax_datetime_value',
+ ],
+ ];
+
+ $form['datetime_result'] = [
+ '#type' => 'markup',
+ '#markup' => '<div id="ajax_datetime_value">No date selected.</div>',
+ ];
+
+ 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 0000000..c45c590
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\FunctionalJavascriptTests\Ajax;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Tests Ajax callbacks on FAPI elements.
+ *
+ * @group Ajax
+ */
+class AjaxCallbacksTest extends JavascriptTestBase {
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = ['ajax_forms_test'];
+
+ /**
+ * Tests if Ajax callback works on date element.
+ */
+ public function testDateTimeAjaxCallback() {
+
+ // Test Ajax callback when date changes.
+ $this->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');
+ }
+
+}