From 4d1823b20529de869cf9e4ba258a9251b8608686 Mon Sep 17 00:00:00 2001 From: GoZ Date: Fri, 9 Oct 2015 10:45:48 +0200 Subject: [PATCH] =?UTF-8?q?Issue=20#2443815=20by=20Dom.,=20rpayanm,=20mgif?= =?UTF-8?q?ford,=20spiritcapsule,=20alexpott,=20prashantgoel,=20joshi.rohi?= =?UTF-8?q?t100,=20borisson=5F,=20valthebald,=20hussainweb,=20Ga=C3=ABlG,?= =?UTF-8?q?=20cwoky,=20jeremypinto,=20DuaelFr,=20GoZ,=20TheodorosPloumis,?= =?UTF-8?q?=20sdstyles:=20#description=5Fdisplay=20broken=20for=20details?= =?UTF-8?q?=20elements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/includes/form.inc | 12 ++++- core/lib/Drupal/Core/Form/FormBuilder.php | 2 + .../system/src/Tests/Form/ElementsDetailsTest.php | 58 ++++++++++++++++++++++ .../system/src/Tests/Form/ElementsLabelsTest.php | 7 +++ core/modules/system/templates/details.html.twig | 26 +++++++++- .../form_test/src/Form/FormTestDescriptionForm.php | 6 +++ .../src/Form/FormTestGroupDetailsForm.php | 48 ++++++++++++++++++ .../themes/classy/templates/form/details.html.twig | 26 ++++++++-- 8 files changed, 180 insertions(+), 5 deletions(-) create mode 100644 core/modules/system/src/Tests/Form/ElementsDetailsTest.php diff --git a/core/includes/form.inc b/core/includes/form.inc index a3d17a7..540966c 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -244,7 +244,17 @@ function template_preprocess_details(&$variables) { $variables['summary_attributes']['aria-pressed'] = $variables['summary_attributes']['aria-expanded']; } $variables['title'] = (!empty($element['#title'])) ? $element['#title'] : ''; - $variables['description'] = (!empty($element['#description'])) ? $element['#description'] : ''; + + if (!empty($element['#description'])) { + $variables['description_display'] = isset($element['#description_display']) ? $element['#description_display'] : 'before'; + $description_attributes = []; + if (!empty($element['#id'])) { + $description_attributes['id'] = $element['#id'] . '--description'; + } + $variables['description']['attributes'] = new Attribute($description_attributes); + $variables['description']['content'] = $element['#description']; + } + $variables['children'] = (isset($element['#children'])) ? $element['#children'] : ''; $variables['value'] = (isset($element['#value'])) ? $element['#value'] : ''; diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index bb7034f..332f81e 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -903,11 +903,13 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state $element['#defaults_loaded'] = TRUE; } // Assign basic defaults common for all form elements. + // NOTE: description_display is below by default, excepted for details. $element += array( '#required' => FALSE, '#attributes' => array(), '#title_display' => 'before', '#description_display' => 'after', + '#description_display' => (isset($element['#type']) && $element['#type'] == 'details') ? 'before' : 'after', '#errors' => NULL, ); diff --git a/core/modules/system/src/Tests/Form/ElementsDetailsTest.php b/core/modules/system/src/Tests/Form/ElementsDetailsTest.php new file mode 100644 index 0000000..84d67c2 --- /dev/null +++ b/core/modules/system/src/Tests/Form/ElementsDetailsTest.php @@ -0,0 +1,58 @@ +drupalGet('form-test/group-details'); + + // Check #description default placement. + $field_id = 'edit-meta'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//details[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]//div/preceding-sibling::div'); + $this->assertTrue(isset($elements[0]), t('Properly places by default the #description element before the form item within details group.')); + + // Check #description placement with #description_display='before'. + $field_id = 'edit-details-before'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//details[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]//div[@id="edit-meta-before"]/preceding-sibling::div[@id="' . $description_id . '"]'); + $this->assertTrue(isset($elements[0]), t('Properly places the #description element before the form item within details group.')); + + // Check #description placement with #description_display='after'. + $field_id = 'edit-details-after'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//details[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]//div[@id="edit-meta-after"]/following-sibling::div[@id="' . $description_id . '"]'); + $this->assertTrue(isset($elements[0]), t('Properly places the #description element after the form item within details group.')); + + // Check if the class is 'visually-hidden' on the form details description + // for the option with #description_display='invisible' and also check that + // the description is placed after the form element. + $field_id = 'edit-details-invisible'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//details[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]//div[@id="edit-meta-invisible"]/following-sibling::div[contains(@class, "visually-hidden")]'); + $this->assertTrue(isset($elements[0]), t('Properly renders the #description element visually-hidden within details group.')); + } +} diff --git a/core/modules/system/src/Tests/Form/ElementsLabelsTest.php b/core/modules/system/src/Tests/Form/ElementsLabelsTest.php index 9a09442..ed42b8d 100644 --- a/core/modules/system/src/Tests/Form/ElementsLabelsTest.php +++ b/core/modules/system/src/Tests/Form/ElementsLabelsTest.php @@ -101,6 +101,13 @@ function testFormLabels() { function testFormDescriptions() { $this->drupalGet('form_test/form-descriptions'); + // Check #description placement with no #description_display, so default is + // 'after' the form item. + $field_id = 'edit-form-textfield-test-description-default'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//input[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]/following-sibling::div[@id="' . $description_id . '"]'); + $this->assertTrue(isset($elements[0]), t('Properly places by default the #description element after the form item.')); + // Check #description placement with #description_display='after'. $field_id = 'edit-form-textfield-test-description-after'; $description_id = $field_id . '--description'; diff --git a/core/modules/system/templates/details.html.twig b/core/modules/system/templates/details.html.twig index cf50eb0..d7e4156 100644 --- a/core/modules/system/templates/details.html.twig +++ b/core/modules/system/templates/details.html.twig @@ -8,6 +8,13 @@ * - errors: (optional) Any errors for this details element, may not be set. * - title: (optional) The title of the element, may not be set. * - description: (optional) The description of the element, may not be set. + * - description_display: (optional) Description display setting. It can have + * these values: + * - before: The description is output before the element. This is the default + * value. + * - after: The description is output after the element. + * - invisible: The description is output after the element, hidden visually + * but available to screen readers. * - children: (optional) The children of the element, may not be set. * - value: (optional) The value of the element, may not be set. * @@ -16,6 +23,12 @@ * @ingroup themeable */ #} +{% + set description_classes = [ + 'description', + description_display == 'invisible' ? 'visually-hidden', + ] +%} {%- if title -%} {{ title }} @@ -27,7 +40,18 @@ {% endif %} - {{ description }} + {% if description_display == 'before' and description.content %} + + {{ description.content }} + + {% endif %} + {{ children }} {{ value }} + + {% if description_display in ['after', 'invisible'] and description.content %} + + {{ description.content }} + + {% endif %} diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php index df4cce5..6479d2b 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php @@ -28,6 +28,12 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { + $form['form_textfield_test_description_default'] = array( + '#type' => 'textfield', + '#title' => 'Textfield test for description default after element', + '#description' => 'Textfield test for description default after element', + ); + $form['form_textfield_test_description_before'] = array( '#type' => 'textfield', '#title' => 'Textfield test for description before element', diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php index d8f5925..e7d22ec 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php @@ -34,6 +34,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['meta'] = array( '#type' => 'details', '#title' => 'Group element', + '#description' => 'Details test for default description position.', '#open' => TRUE, '#group' => 'details', ); @@ -41,6 +42,53 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#type' => 'textfield', '#title' => 'Nest in details element', ); + $form['details_before'] = array( + '#type' => 'details', + '#title' => 'Details test for description before element', + '#description' => 'Details test for description before element.', + '#description_display' => 'before', + ); + $form['meta_before'] = array( + '#type' => 'container', + '#title' => 'Group element', + '#group' => 'details_before', + ); + $form['meta_before']['element'] = array( + '#type' => 'textfield', + '#title' => 'Nest in container element', + ); + + $form['details_after'] = array( + '#type' => 'details', + '#title' => 'Details test for description after element', + '#description' => 'Details test for description after element.', + '#description_display' => 'after', + ); + $form['meta_after'] = array( + '#type' => 'container', + '#title' => 'Group element', + '#group' => 'details_after', + ); + $form['meta_after']['element'] = array( + '#type' => 'textfield', + '#title' => 'Nest in container element', + ); + + $form['details_invisible'] = array( + '#type' => 'details', + '#title' => 'Details test for visually-hidden description', + '#description' => 'Details test for visually-hidden description.', + '#description_display' => 'invisible', + ); + $form['meta_invisible'] = array( + '#type' => 'container', + '#title' => 'Group element', + '#group' => 'details_invisible', + ); + $form['meta_invisible']['element'] = array( + '#type' => 'textfield', + '#title' => 'Nest in container element', + ); return $form; } diff --git a/core/themes/classy/templates/form/details.html.twig b/core/themes/classy/templates/form/details.html.twig index a4ce6f6..5f58228 100644 --- a/core/themes/classy/templates/form/details.html.twig +++ b/core/themes/classy/templates/form/details.html.twig @@ -8,12 +8,25 @@ * - errors: (optional) Any errors for this details element, may not be set. * - title: (optional) The title of the element, may not be set. * - description: (optional) The description of the element, may not be set. + * - description_display: (optional) Description display setting. It can have + * these values: + * - before: The description is output before the element. This is the default + * value. + * - after: The description is output after the element. + * - invisible: The description is output after the element, hidden visually + * but available to screen readers. * - children: (optional) The children of the element, may not be set. * - value: (optional) The value of the element, may not be set. * * @see template_preprocess_details() */ #} +{% + set description_classes = [ + 'description', + description_display == 'invisible' ? 'visually-hidden', + ] +%} {%- if title -%} {{ title }} @@ -24,14 +37,21 @@ {{ errors }} {% endif %} - {%- if description -%} -
{{ description }}
- {%- endif -%} + {% if description_display == 'before' and description.content %} + + {{ description.content }} + + {% endif %} {%- if children -%} {{ children }} {%- endif -%} {%- if value -%} {{ value }} {%- endif -%} + {% if description_display in ['after', 'invisible'] and description.content %} + + {{ description.content }} + + {% endif %} -- 1.9.3 (Apple Git-50)