1 form.inc | theme_form_element($variables) |
Returns HTML for a form element.
Each form element is wrapped in a DIV container having the following CSS classes:
- form-item: Generic for all form elements.
- form-type-#type: The internal element #type.
- form-item-#name: The internal form element #name (usually derived from the $form structure and set via form_builder()).
- form-disabled: Only set if the form element is #disabled.
In addition to the element itself, the DIV contains a label and an optional description. The label and description can be positioned by the #title_display and #description_display properties respectively.
The optional #title_display property can have these values:
- before: The label is output before the element. This is the default. The label includes the #title and the required marker, if #required.
- after: The label is output after the element. For example, this is used for radio and checkbox #type elements as set in system_element_info(). If the #title is empty but the field is #required, the label will contain only the required marker.
- invisible: Labels are critical for screen readers to enable them to properly navigate through forms but can be visually distracting. This property hides the label for everyone except screen readers.
- attribute: Set the title attribute on the element to create a tooltip but output no label element. This is supported only for checkboxes and radios in form_pre_render_conditional_form_element(). It is used where a visual 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.
If the #title property is not set, then the label and any required marker will not be output, regardless of the #title_display or #required values. This can be useful in cases such as the password_confirm element, which creates children elements that have their own labels and required markers, but the parent element should have neither. Use this carefully because a field without an associated label can cause accessibility challenges.
The optional #description_display property can have these values:
- after (the default for all elements except for fieldset): The description is output after the element.
- before (the default for fieldsets): The description is output before the element, after the label (if not visually hidden).
- invisible: The description is output between the label and the main form element, hidden visually but available to screen readers.
Parameters
array $variables: An associative array containing:
- element: An associative array containing the properties of the element. Properties used: #type, #name, #title, #title_display, #id, #required, #description, #description_display, #children.
Related topics
File
- core/
includes/ form.inc, line 4910 - Functions for form and batch generation and processing.
Code
function theme_form_element($variables) {
$element = &$variables['element'];
// This function is invoked as theme wrapper, but the rendered form element
// may not necessarily have been processed by form_builder().
$element += array(
'#title_display' => 'before',
'#description_display' => 'after',
'#wrapper_attributes' => array(),
);
$attributes = $element['#wrapper_attributes'];
// Add element #id for #type 'item'.
if (isset($element['#markup']) && !empty($element['#id'])) {
$attributes['id'] = $element['#id'];
}
// Add element's #type and #name as class to aid with JS/CSS selectors.
$attributes['class'][] = 'form-item';
if (!empty($element['#type'])) {
$attributes['class'][] = 'form-type-' . strtr($element['#type'], '_', '-');
if (isset($element['#parents']) && form_get_error($element) !== NULL && !empty($element['#validated'])) {
$attributes['class'][] = 'form-error';
}
}
if (!empty($element['#name'])) {
$attributes['class'][] = 'form-item-' . strtr($element['#name'], array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
}
// Add a class for disabled elements to facilitate cross-browser styling.
if (!empty($element['#attributes']['disabled'])) {
$attributes['class'][] = 'form-disabled';
}
// Add indentation.
if (isset($element['#indentation'])) {
$attributes['class'][] = 'form-item-indentation';
$attributes['class'][] = 'form-item-indentation-' . $element['#indentation'];
$attributes['data-indentation-depth'] = $element['#indentation'];
}
$output = '<div' . backdrop_attributes($attributes) . '>' . "\n";
// If #title is not set, we don't display any label or required marker.
if (!isset($element['#title'])) {
$element['#title_display'] = 'none';
}
$description_before = '';
$description_after = '';
if (!empty($element['#description'])) {
$description = theme('form_element_description', $variables);
switch ($element['#description_display']) {
case 'before':
// It is preferable for screen readers if the help text is near/after
// the label of the element. So treat it the same as "before" when it
// comes to its placement in that case.
$description_before = $description;
break;
case 'after':
case 'invisible':
$description_after = $description;
break;
}
}
$prefix = isset($element['#field_prefix']) ? '<span class="field-prefix">' . $element['#field_prefix'] . '</span> ' : '';
$suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix">' . $element['#field_suffix'] . '</span>' : '';
$main_element = $description_before . $prefix . $element['#children'] . $suffix;
switch ($element['#title_display']) {
case 'before':
case 'invisible':
$output .= ' ' . theme('form_element_label', $variables) . ' ' . $main_element . "\n";
break;
case 'after':
$output .= ' ' . $main_element . ' ' . theme('form_element_label', $variables) . "\n";
break;
case 'none':
case 'attribute':
// Output no label and no required marker; only the children.
$output .= ' ' . $main_element . "\n";
break;
}
$output .= $description_after . "</div>\n";
return $output;
}