diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index d3bedc1..60728dc 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -836,6 +836,7 @@ public function doBuildForm($form_id, &$element, &$form_state) { '#required' => FALSE, '#attributes' => array(), '#title_display' => 'before', + '#description_display' => 'after', '#errors' => NULL, ); diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ElementsLabelsTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ElementsLabelsTest.php index b002635..039b9fa 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Form/ElementsLabelsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Form/ElementsLabelsTest.php @@ -23,8 +23,8 @@ class ElementsLabelsTest extends WebTestBase { public static function getInfo() { return array( - 'name' => 'Form element and label output test', - 'description' => 'Test form element labels, required markers and associated output.', + 'name' => 'Form element label and description test', + 'description' => 'Test form element labels, required markers, descriptions and associated output.', 'group' => 'Form API', ); } @@ -97,4 +97,29 @@ function testFormLabels() { $elements = $this->xpath('//div[@id="edit-form-radios-title-attribute"]'); $this->assertEqual($elements[0]['title'], 'Radios test' . ' (' . t('Required') . ')', 'Title attribute found.'); } + + /** + * Test description of form elements with different placement options. + */ + function testFormDescriptions() { + $test = $this->drupalGet('form_test/form-descriptions'); + + // Check #description placement with #description_display='after'. + $field_id = 'edit-form-textfield-test-description-after'; + $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 the #description element after the form item.')); + + // Check #description placement with #description_display='before'. + $field_id = 'edit-form-textfield-test-description-before'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//input[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]/preceding-sibling::div[@id="' . $description_id . '"]'); + $this->assertTrue(isset($elements[0]), t('Properly places the #description element before the form item.')); + + // Check #description placement with #description_display='invisible'. + $field_id = 'edit-form-textfield-test-description-invisible'; + $description_id = $field_id . '--description'; + $elements = $this->xpath('//input[@id="' . $field_id . '" and @aria-describedby="' . $description_id . '"]/following-sibling::div[@class="visually-hidden"]'); + $this->assertTrue(isset($elements[0]), t('Properly renders the #description element visually-hidden.')); + } } diff --git a/core/modules/system/templates/form-element.html.twig b/core/modules/system/templates/form-element.html.twig index ea4d90f..053280a 100644 --- a/core/modules/system/templates/form-element.html.twig +++ b/core/modules/system/templates/form-element.html.twig @@ -26,6 +26,10 @@ * label is not needed, such as a table of checkboxes where the row and * column provide the context. The tooltip will include the title and * required marker. + * - description_display: Description display setting. It can have these values: + * - before: The description is output before the element. + * - after: The description is output after the element. This is the default + * value. * - description: (optional) A list of description properties containing: * - content: A description of the form element, may not be set. * - attributes: (optional) A list of HTML attributes to apply to the @@ -43,6 +47,11 @@ {% if prefix is not empty %} {{ prefix }} {% endif %} + {% if description_display == 'before' and description.content %} + + {{ description.content }} + + {% endif %} {{ children }} {% if suffix is not empty %} {{ suffix }} @@ -50,7 +59,7 @@ {% if label_display == 'after' %} {{ label }} {% endif %} - {% if description.content %} + {% if description_display == 'after' and description.content %} {{ description.content }}