diff --git a/core/includes/form.inc b/core/includes/form.inc index 375f178671d..68a16cd515b 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -3870,19 +3870,19 @@ function form_validate_machine_name(&$element, &$form_state) { } /** - * Arranges details into groups. + * Arranges elements into groups. * * @param $element * An associative array containing the properties and children of the - * details. Note that $element must be taken by reference here, so processed + * element. Note that $element must be taken by reference here, so processed * child elements are taken over into $form_state. * @param $form_state - * The $form_state array for the form this details belongs to. + * The $form_state array for the form this element belongs to. * * @return * The processed element. */ -function form_process_details(&$element, &$form_state) { +function form_process_group(&$element, &$form_state) { $parents = implode('][', $element['#parents']); // Each details element forms a new group. The #type 'vertical_tabs' basically @@ -3904,14 +3904,14 @@ function form_process_details(&$element, &$form_state) { } /** - * Adds members of this group as actual elements for rendering. + * Adds form element theming to details. * * @param $element * An associative array containing the properties and children of the * details. * * @return - * The modified element with all group members. + * The modified element. */ function form_pre_render_details($element) { // The .form-wrapper class is required for #states to treat details like @@ -3929,10 +3929,25 @@ function form_pre_render_details($element) { $element['#attributes']['open'] = 'open'; } - // Details may be rendered outside of a Form API context. + return $element; +} + +/** + * Adds members of this group as actual elements for rendering. + * + * @param $element + * An associative array containing the properties and children of the + * element. + * + * @return + * The modified element with all group members. + */ +function form_pre_render_group($element) { + // The element may be rendered outside of a Form API context. if (!isset($element['#parents']) || !isset($element['#groups'])) { return $element; } + // Inject group member elements belonging to this group. $parents = implode('][', $element['#parents']); $children = element_children($element['#groups'][$parents]); diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php index 3b7f935ddf3..e3521ccf6a4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php @@ -107,4 +107,23 @@ class ElementTest extends WebTestBase { $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " button-danger ")]'))); } + /** + * Tests the #group property. + */ + function testGroupElements() { + $this->drupalGet('form-test/group-details'); + $elements = $this->xpath('//div[@class="details-wrapper"]//div[@class="details-wrapper"]//label'); + $this->assertTrue(count($elements) == 1); + $this->drupalGet('form-test/group-container'); + $elements = $this->xpath('//div[@id="edit-container"]//div[@class="details-wrapper"]//label'); + $this->assertTrue(count($elements) == 1); + $this->drupalGet('form-test/group-fieldset'); + $elements = $this->xpath('//fieldset[@id="edit-fieldset"]//div[@id="edit-meta"]//label'); + $this->assertTrue(count($elements) == 1); + $this->drupalGet('form-test/group-vertical-tabs'); + $elements = $this->xpath('//div[@class="vertical-tabs-panes"]//details[@id="edit-meta"]//label'); + $this->assertTrue(count($elements) == 1); + $elements = $this->xpath('//div[@class="vertical-tabs-panes"]//details[@id="edit-meta-2"]//label'); + $this->assertTrue(count($elements) == 1); + } } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 65b19149f2c..336f84b5008 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -543,15 +543,16 @@ function system_element_info() { ); $types['fieldset'] = array( '#value' => NULL, - '#process' => array('ajax_process_form'), + '#process' => array('form_process_group', 'ajax_process_form'), + '#pre_render' => array('form_pre_render_group'), '#theme_wrappers' => array('fieldset'), ); $types['details'] = array( '#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL, - '#process' => array('form_process_details', 'ajax_process_form'), - '#pre_render' => array('form_pre_render_details'), + '#process' => array('form_process_group', 'ajax_process_form'), + '#pre_render' => array('form_pre_render_details', 'form_pre_render_group'), '#theme_wrappers' => array('details'), ); $types['vertical_tabs'] = array( @@ -570,7 +571,8 @@ function system_element_info() { ); $types['container'] = array( - '#process' => array('form_process_container'), + '#process' => array('form_process_group', 'form_process_container'), + '#pre_render' => array('form_pre_render_group'), '#theme_wrappers' => array('container'), ); $types['actions'] = array( diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module index 9fd4bcb2f81..8e1992ce454 100644 --- a/core/modules/system/tests/modules/form_test/form_test.module +++ b/core/modules/system/tests/modules/form_test/form_test.module @@ -314,6 +314,31 @@ function form_test_menu() { 'access callback' => TRUE, ); + $items['form-test/group-details'] = array( + 'title' => 'Group details testing', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_group_details'), + 'access callback' => TRUE, + ); + $items['form-test/group-container'] = array( + 'title' => 'Group container testing', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_group_container'), + 'access callback' => TRUE, + ); + $items['form-test/group-fieldset'] = array( + 'title' => 'Group fieldset testing', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_group_fieldset'), + 'access callback' => TRUE, + ); + $items['form-test/group-vertical-tabs'] = array( + 'title' => 'Group vertical tabs testing', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_group_vertical_tabs'), + 'access callback' => TRUE, + ); + return $items; } @@ -2333,3 +2358,90 @@ function form_test_button_class($form, &$form_state) { ); return $form; } + +/** + * Builds a simple form to test the #group property on #type 'details'. + */ +function form_test_group_details() { + $form['details'] = array( + '#type' => 'details', + '#title' => 'Root element', + ); + $form['meta'] = array( + '#type' => 'details', + '#title' => 'Group element', + '#group' => 'details', + ); + $form['meta']['element'] = array( + '#type' => 'textfield', + '#title' => 'Nest in details element', + ); + return $form; +} + +/** + * Builds a simple form to test the #group property on #type 'container'. + */ +function form_test_group_container() { + $form['container'] = array( + '#type' => 'container', + ); + $form['meta'] = array( + '#type' => 'details', + '#title' => 'Group element', + '#group' => 'container', + ); + $form['meta']['element'] = array( + '#type' => 'textfield', + '#title' => 'Nest in details element', + ); + return $form; +} + +/** + * Builds a simple form to test the #group property on #type 'fieldset'. + */ +function form_test_group_fieldset() { + $form['fieldset'] = array( + '#type' => 'fieldset', + '#title' => 'Fieldset', + ); + $form['meta'] = array( + '#type' => 'container', + '#title' => 'Group element', + '#group' => 'fieldset', + ); + $form['meta']['element'] = array( + '#type' => 'textfield', + '#title' => 'Nest in container element', + ); + return $form; +} + +/** + * Builds a simple form to test the #group property on #type 'vertical_tabs'. + */ +function form_test_group_vertical_tabs() { + $form['vertical_tabs'] = array( + '#type' => 'vertical_tabs', + ); + $form['meta'] = array( + '#type' => 'details', + '#title' => 'First group element', + '#group' => 'vertical_tabs', + ); + $form['meta']['element'] = array( + '#type' => 'textfield', + '#title' => 'First nested element in details element', + ); + $form['meta_2'] = array( + '#type' => 'details', + '#title' => 'Second group element', + '#group' => 'vertical_tabs', + ); + $form['meta_2']['element_2'] = array( + '#type' => 'textfield', + '#title' => 'Second nested element in details element', + ); + return $form; +}