diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index d0114e2..271681b 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -108,6 +108,10 @@ function datetime_theme() { 'template' => 'datetime-wrapper', 'render element' => 'element', ), + 'datetime_fieldset_wrapper' => array( + 'template' => 'datetime-fieldset-wrapper', + 'render element' => 'element', + ), ); } @@ -250,7 +254,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')); @@ -264,6 +274,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 a411eb4..9ead895 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php +++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php @@ -68,7 +68,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'; @@ -77,6 +76,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; @@ -86,6 +86,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 eefd3c3..5fa0bbb 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-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 ac1fa33..504a2d2 100644 --- a/core/modules/system/css/system.module.css +++ b/core/modules/system/css/system.module.css @@ -281,6 +281,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/css/style.css b/core/themes/seven/css/style.css index ff81295..d936a34 100644 --- a/core/themes/seven/css/style.css +++ b/core/themes/seven/css/style.css @@ -1173,6 +1173,9 @@ div.admin-options div.form-item { details.fieldset-no-legend { padding-top: 0; } +.field-type-datetime .form-item { + border: none; +} /** * Being extra safe here and scoping this to the add view wizard form (where