diff --git a/core/includes/form.inc b/core/includes/form.inc index 5663ac6..ce15084 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -2849,6 +2849,7 @@ function form_process_date($element) { } $element['#tree'] = TRUE; + $element['#composite'] = TRUE; // Determine the order of day, month, year in the site's chosen date format. $format = variable_get('date_format_short', 'm/d/Y - H:i'); @@ -2940,6 +2941,7 @@ function weight_value(&$form) { function form_process_radios($element) { if (count($element['#options']) > 0) { $weight = 0; + $element['#composite'] = TRUE; foreach ($element['#options'] as $key => $choice) { // Maintain order of options as defined in #options, in case the element // defines custom option sub-elements, but does not define all option @@ -3073,6 +3075,7 @@ function form_process_checkboxes($element) { $element['#default_value'] = array(); } $weight = 0; + $element['#composite'] = TRUE; foreach ($element['#options'] as $key => $choice) { // Integer 0 is not a valid #return_value, so use '0' instead. // @see form_type_checkbox_value(). @@ -3959,36 +3962,69 @@ function theme_form_element($variables) { } $output = '' . "\n"; + // Composite elements consist of more than one HTML form control. These must + // be grouped by a fieldset. + $composite = false; + if (isset($element['#composite']) && $element['#composite'] === true) { + $composite = true; + } + + if ($composite) { + $output .= ' 'fieldset-invisible')) . '>'; + } + // If #title is not set, we don't display any label or required marker. if (!isset($element['#title'])) { $element['#title_display'] = 'none'; } $prefix = isset($element['#field_prefix']) ? '' . $element['#field_prefix'] . ' ' : ''; $suffix = isset($element['#field_suffix']) ? ' ' . $element['#field_suffix'] . '' : ''; + $children = ' ' . $prefix . $element['#children'] . $suffix; + + // Generate the title, either a legend or a label, only if the title will be + // used. + if (!in_array($element['#title_display'], array('none', 'attribute'))) { + if ($composite) { + $attributes = array(); + if ($element['#title_display'] == 'invisible') { + $attributes['class'] = 'element-invisible'; + } + $title = '' . $element['#title']; + if (!empty($element['#required'])) { + $title .= theme('form_required_marker', array('element' => $element)); + } + $title .= ''; + } else { + $title = ' ' . theme('form_element_label', $variables); + } + } switch ($element['#title_display']) { case 'before': case 'invisible': - $output .= ' ' . theme('form_element_label', $variables); - $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n"; + $output .= $title . $children; break; case 'after': - $output .= ' ' . $prefix . $element['#children'] . $suffix; - $output .= ' ' . theme('form_element_label', $variables) . "\n"; + $output .= $children . $title; break; case 'none': case 'attribute': // Output no label and no required marker, only the children. - $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n"; + $output .= $children; break; } + $output .= "\n"; if (!empty($element['#description'])) { $output .= '
' . $element['#description'] . "
\n"; } + if ($composite) { + $output .= ''; + } + $output .= "\n"; return $output; diff --git a/core/modules/simpletest/tests/form.test b/core/modules/simpletest/tests/form.test index 784da88..cf395c7 100644 --- a/core/modules/simpletest/tests/form.test +++ b/core/modules/simpletest/tests/form.test @@ -68,7 +68,7 @@ class FormsTestCase extends DrupalWebTestCase { $elements['file']['empty_values'] = $empty_strings; // Regular expression to find the expected marker on required elements. - $required_marker_preg = '@\*@'; + $required_marker_preg = '@<(label|legend).*\*@'; // Go through all the elements and all the empty values for them. foreach ($elements as $type => $data) { diff --git a/core/modules/system/system.theme.css b/core/modules/system/system.theme.css index 7121813..11bb83e 100644 --- a/core/modules/system/system.theme.css +++ b/core/modules/system/system.theme.css @@ -188,6 +188,48 @@ html.js fieldset.collapsed > legend .fieldset-legend { } /** + * Invisible fieldsets. + * + * @see theme_form_element() + */ +fieldset.fieldset-invisible { + margin: 0; + padding: 0; + border: none; + display: inherit; +} +fieldset.fieldset-invisible > legend { + margin: 0; + padding: 0; + border: none; + outline: 0; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; + + border-radius: 0; + color: inherit; + background-color: transparent; + background-image: none; + + display: block; + font-weight: bold; + + position: static; + left: 0; + right: 0; + top: 0; + bottom: 0; + + text-indent: 0; + text-shadow: none; + line-height: normal; + width: auto; + height: auto; +} + +/** * TableDrag behavior. * * @see tabledrag.js