Commit 57762d19 authored by catch's avatar catch

Issue #2783615 by k4v, Dom., dawehner: Datetime FAPI element type do not allow AJAX via #ajax API

parent e64d7536
...@@ -45,6 +45,7 @@ public function getInfo() { ...@@ -45,6 +45,7 @@ public function getInfo() {
], ],
'#process' => [ '#process' => [
[$class, 'processDatetime'], [$class, 'processDatetime'],
[$class, 'processAjaxForm'],
[$class, 'processGroup'], [$class, 'processGroup'],
], ],
'#pre_render' => [ '#pre_render' => [
...@@ -311,6 +312,25 @@ public static function processDatetime(&$element, FormStateInterface $form_state ...@@ -311,6 +312,25 @@ public static function processDatetime(&$element, FormStateInterface $form_state
return $element; 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. * Validation callback for a datetime element.
* *
......
...@@ -33,7 +33,10 @@ public function getInfo() { ...@@ -33,7 +33,10 @@ public function getInfo() {
return [ return [
'#input' => TRUE, '#input' => TRUE,
'#theme' => 'input__date', '#theme' => 'input__date',
'#process' => [[$class, 'processDate']], '#process' => [
[$class, 'processAjaxForm'],
[$class, 'processDate'],
],
'#pre_render' => [[$class, 'preRenderDate']], '#pre_render' => [[$class, 'preRenderDate']],
'#theme_wrappers' => ['form_element'], '#theme_wrappers' => ['form_element'],
'#attributes' => ['type' => 'date'], '#attributes' => ['type' => 'date'],
......
...@@ -269,6 +269,7 @@ public static function preRenderAjaxForm($element) { ...@@ -269,6 +269,7 @@ public static function preRenderAjaxForm($element) {
$element['#attributes']['data-disable-refocus'] = "true"; $element['#attributes']['data-disable-refocus'] = "true";
} }
// Add a reasonable default event handler if none was specified. // Add a reasonable default event handler if none was specified.
if (isset($element['#ajax']) && !isset($element['#ajax']['event'])) { if (isset($element['#ajax']) && !isset($element['#ajax']['event'])) {
switch ($element['#type']) { switch ($element['#type']) {
...@@ -308,6 +309,7 @@ public static function preRenderAjaxForm($element) { ...@@ -308,6 +309,7 @@ public static function preRenderAjaxForm($element) {
case 'radio': case 'radio':
case 'checkbox': case 'checkbox':
case 'select': case 'select':
case 'date':
$element['#ajax']['event'] = 'change'; $element['#ajax']['event'] = 'change';
break; break;
......
...@@ -38,3 +38,11 @@ ajax_forms_test.image_button_form: ...@@ -38,3 +38,11 @@ ajax_forms_test.image_button_form:
requirements: requirements:
_access: 'TRUE' _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'
...@@ -22,6 +22,18 @@ public function selectCallback($form, FormStateInterface $form_state) { ...@@ -22,6 +22,18 @@ public function selectCallback($form, FormStateInterface $form_state) {
return $response; 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. * Ajax callback triggered by checkbox.
*/ */
......
<?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) {}
}
<?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');
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment