diff --git a/core/core.libraries.yml b/core/core.libraries.yml index 080fb37..f3cc4d4 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -132,6 +132,16 @@ drupal.collapse: - core/drupal.form - core/jquery.once +drupal.date: + version: VERSION + js: + misc/date.js: {} + dependencies: + - core/drupal + - core/drupalSettings + - core/modernizr + - core/jquery.ui.datepicker + drupal.debounce: version: VERSION js: diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php index d298e21..fc6f4d5 100644 --- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php +++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php @@ -267,6 +267,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state '#attributes' => $element['#attributes'] + $extra_attributes, '#required' => $element['#required'], '#size' => max(12, strlen($element['#value']['date'])), + '#date_date_format' => $element['#date_date_format'], ); // Allows custom callbacks to alter the element. diff --git a/core/lib/Drupal/Core/Render/Element/Date.php b/core/lib/Drupal/Core/Render/Element/Date.php index 8585cb3..db04fa9 100644 --- a/core/lib/Drupal/Core/Render/Element/Date.php +++ b/core/lib/Drupal/Core/Render/Element/Date.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Render\Element; +use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; /** @@ -29,6 +30,9 @@ public function getInfo() { return array( '#input' => TRUE, '#theme' => 'input__date', + '#process' => array( + array($class, 'processDate'), + ), '#pre_render' => array( array($class, 'preRenderDate'), ), @@ -37,11 +41,49 @@ public function getInfo() { } /** + * Processes a date form element. + * + * @param array $element + * The form element to process. Properties used: + * - #attributes: An associative array containing: + * - type: The type of date field rendered. + * - #date_date_format: The date format used in PHP formats. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * @param array $complete_form + * The complete form structure. + * + * @return array + * The processed element. + */ + public static function processDate(&$element, FormStateInterface $form_state, &$complete_form) { + // Attach JS support, if we can determine which date format should be used. + if ($element['#attributes']['type'] == 'date' && !empty($element['#date_date_format'])) { + $element['#attached']['library'][] = 'core/drupal.date'; + $format = $element['#date_date_format']; + // Convert the format into jQuery UI settings. + $format = str_replace('Y', 'yy', $format); + $format = str_replace('m', 'mm', $format); + $format = str_replace('d', 'dd', $format); + $settings = array('dateFormat' => $format); + if (!empty($element['#attributes']['min'])) { + $settings['minDate'] = $element['#attributes']['min']; + } + if (!empty($element['#attributes']['max'])) { + $settings['maxDate'] = $element['#attributes']['max']; + } + $element['#attached']['drupalSettings']['date'][$element['#id']] = $settings; + } + return $element; + } + + /** * Adds form-specific attributes to a 'date' #type element. * * Supports HTML5 types of 'date', 'datetime', 'datetime-local', and 'time'. * Falls back to a plain textfield. Used as a sub-element by the datetime * element type. + * Adds JS fallback support for browsers not understanding date types. * * @param array $element * An associative array containing the properties of the element. diff --git a/core/misc/date.js b/core/misc/date.js new file mode 100644 index 0000000..e02041c --- /dev/null +++ b/core/misc/date.js @@ -0,0 +1,28 @@ +(function ($, Modernizr, Drupal, drupalSettings) { + + "use strict"; + + /** + * Attach datepicker fallback on date elements. + */ + Drupal.behaviors.date = { + /** + * Attaches the behavior. + * + * @param settings.date + * A list of elements to process, keyed by the HTML ID of the form element + * containing the human-readable value. Each element is an datepicker + * settings object. + */ + attach: function (context, settings) { + var $context = $(context); + // Only act if the browser doesn't support date input type. + if (Modernizr.inputtypes.date === false) { + $.each(settings.date, function(id, datepickerSettings) { + $context.find("#" + id).datepicker(datepickerSettings); + }); + } + } + }; + +})(jQuery, Modernizr, Drupal, drupalSettings);