diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index b5f98dd..bc3c690 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -107,6 +107,10 @@ function datetime_theme() { 'template' => 'datetime-wrapper', 'render element' => 'element', ), + 'datetime_fieldset_wrapper' => array( + 'template' => 'datetime-fieldset-wrapper', + 'render element' => 'element', + ), ); } @@ -249,7 +253,13 @@ function template_preprocess_datetime_wrapper(&$variables) { } if (!empty($element['#description'])) { + // Add aria-describedby attribute to title tag for screen readers. $variables['description'] = $element['#description']; + $variables['attributes']['class'][] = 'description'; + // Associate the description with the aria-describedby attribute. + $variables['attributes']['id'] = $variables['attributes']['aria-describedby']; + // Remove aria-describedby attribute as it shouldn't be visible here. + unset($variables['attributes']['aria-describedby']); } $title_attributes = array('class' => array('label')); @@ -263,6 +273,46 @@ function template_preprocess_datetime_wrapper(&$variables) { } /** + * Prepares variables for datetime fieldset form wrapper templates. + * + * Default template: datetime-fieldset-wrapper.html.twig. + * + * @param array $variables + * An associative array containing: + * - element: An associative array containing the properties of the element. + * Properties used: #attributes, ,#content, #description, #id, #title, + * #required. + */ +function template_preprocess_datetime_fieldset_wrapper(&$variables) { + $element = $variables['element']; + $variables['content'] = $element['#children']; + $variables['attributes'] = $element['#attributes']; + $variables['attributes']['class'][] = 'form-item'; + $legend_attributes = array(); + if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') { + $legend_attributes['class'][] = 'visually-hidden'; + } + $variables['legend']['attributes'] = new Attribute($legend_attributes); + if (!empty($element['#title'])) { + $variables['legend']['title'] = $element['#title']; + } +// $variables['legend']['title'] = (isset($element['#title']) && $element['#title'] !== '') ? Xss::filterAdmin($element['#title']) : ''; + $legend_span_attributes = array('class' => array('fieldset-legend')); + if (!empty($element['#required'])) { + $legend_span_attributes['class'][] = 'form-required'; + $variables['legend_span']['attributes'] = new Attribute($legend_span_attributes); + } + if (!empty($element['#description'])) { + $description_attributes = array( + 'class' => 'description', + 'id' => $element['#attributes']['aria-describedby'], + ); + $variables['description']['attributes'] = new Attribute($description_attributes); + $variables['description']['content'] = $element['#description']; + } +} + +/** * Expands a datetime element type into date and/or time elements. * * All form elements are designed to have sane defaults so any or all can be diff --git a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php index 00426c0..5ccf9a5 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php +++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php @@ -67,7 +67,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen // title because the actual title display is handled at a higher level by // the Field module. - $element['#theme_wrappers'][] = 'datetime_wrapper'; $element['#attributes']['class'][] = 'container-inline'; $element['#element_validate'][] = 'datetime_datetime_widget_validate'; @@ -76,6 +75,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen case DateTimeItem::DATETIME_TYPE_DATE: $date_type = 'date'; $time_type = 'none'; + $element['#theme_wrappers'][] = 'datetime_wrapper'; $date_format = $this->dateStorage->load('html_date')->getPattern(); $time_format = ''; $element_format = $date_format; @@ -85,6 +85,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen default: $date_type = 'date'; $time_type = 'time'; + $element['#theme_wrappers'][] = 'datetime_fieldset_wrapper'; $date_format = $this->dateStorage->load('html_date')->getPattern(); $time_format = $this->dateStorage->load('html_time')->getPattern(); $element_format = $date_format . ' ' . $time_format; diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php index 7de2742..9abd7ea 100644 --- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php @@ -162,6 +162,7 @@ function testDatetimeField() { $this->drupalGet('entity_test/add'); $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.'); + $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/fieldset/legend/span[contains(@class, "form-required")]', TRUE, 'Required markup found'); // Submit a valid date and ensure it is accepted. $value = '2012-12-31 00:00:00'; diff --git a/core/modules/datetime/templates/datetime-fieldset-wrapper.html.twig b/core/modules/datetime/templates/datetime-fieldset-wrapper.html.twig new file mode 100644 index 0000000..4855700 --- /dev/null +++ b/core/modules/datetime/templates/datetime-fieldset-wrapper.html.twig @@ -0,0 +1,34 @@ +{# +/** + * @file + * Default theme implementation of a datetime fieldset form wrapper. + * + * Available variables: + * - attributes: HTML attributes for the fieldset element. + * - required: The required marker or empty if the associated fieldset is + * not required. + * - legend: The legend element containing the following properties: + * - title: Title of the fieldset, intended for use as the text of the legend. + * - attributes: HTML attributes to apply to the legend. + * - description: The description element containing the following properties: + * - content: The description content of the fieldset. + * - attributes: HTML attributes to apply to the description container. + * - content: The form element to be output. + * + * @see template_preprocess_datetime_fieldset_wrapper() + * + * @ingroup themeable + */ +#} + + {% if legend.title is not empty or required -%} + {# Always wrap fieldset legends in a SPAN for CSS positioning. #} + {{ legend.title }}{{ required }} + {%- endif %} +
+ {{ content }} + {% if description.content %} + {{ description.content }}
+ {% endif %} + + \ No newline at end of file diff --git a/core/modules/datetime/templates/datetime-wrapper.html.twig b/core/modules/datetime/templates/datetime-wrapper.html.twig index 5660cf5..2bc9be0 100644 --- a/core/modules/datetime/templates/datetime-wrapper.html.twig +++ b/core/modules/datetime/templates/datetime-wrapper.html.twig @@ -8,6 +8,7 @@ * - title: The title of the form element. * - title_attributes: HTML attributes for the title wrapper. * - description: Description text for the form element. + * - attributes: Attributes for the description field. * * @see template_preprocess_datetime_wrapper() * @@ -19,5 +20,5 @@ {% endif %} {{ content }} {% if description %} -
{{ description }}
+ {{ description }} {% endif %} diff --git a/core/modules/system/css/system.module.css b/core/modules/system/css/system.module.css index 74bc83f..6ca64fb 100644 --- a/core/modules/system/css/system.module.css +++ b/core/modules/system/css/system.module.css @@ -264,6 +264,9 @@ tr .ajax-progress-throbber .throbber { .container-inline .details-wrapper { display: block; } +.container-inline .description { + display: block; +} /** * Prevent text wrapping. diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig index 52d410f..23cebfc 100644 --- a/core/modules/system/templates/fieldset.html.twig +++ b/core/modules/system/templates/fieldset.html.twig @@ -16,6 +16,7 @@ * - children: The rendered child elements of the fieldset. * - prefix: The content to add before the fieldset children. * - suffix: The content to add after the fieldset children. + * - content: The form element to be output. * * @see template_preprocess_fieldset() * @@ -32,6 +33,7 @@ {{ prefix }} {% endif %} {{ children }} + {{ content }} {% if suffix %} {{ suffix }} {% endif %} diff --git a/core/themes/seven/style.css b/core/themes/seven/css/style.css index 460ef24..f7dd5f4 100644 --- a/core/themes/seven/css/style.css +++ b/core/themes/seven/css/style.css @@ -1544,3 +1544,8 @@ details.fieldset-no-legend { border: none; text-decoration: underline; } + +.field-type-datetime .form-item { + border: none; +} +