4.6.x theme.inc theme_form_element($title, $value, $description = NULL, $id = NULL, $required = FALSE, $error = FALSE)
4.7.x theme.inc theme_form_element($title, $value, $description = NULL, $id = NULL, $required = FALSE, $error = FALSE)
5.x form.inc theme_form_element($element, $value)
6.x form.inc theme_form_element($element, $value)
7.x 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 for the element based on the optional #title_display property, and an optional #description.

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.

Parameters

$variables: An associative array containing:

  • element: An associative array containing the properties of the element. Properties used: #title, #title_display, #description, #id, #required, #children, #type, #name.

Related topics

File

includes/form.inc, line 4208
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',
  );

  // 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'] = array(
    'form-item',
  );
  if (!empty($element['#type'])) {
    $attributes['class'][] = 'form-type-' . strtr($element['#type'], '_', '-');
  }
  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';
  }
  $output = '<div' . drupal_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';
  }
  $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>' : '';
  switch ($element['#title_display']) {
    case 'before':
    case 'invisible':
      $output .= ' ' . theme('form_element_label', $variables);
      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
      break;
    case 'after':
      $output .= ' ' . $prefix . $element['#children'] . $suffix;
      $output .= ' ' . theme('form_element_label', $variables) . "\n";
      break;
    case 'none':
    case 'attribute':

      // Output no label and no required marker, only the children.
      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
      break;
  }
  if (!empty($element['#description'])) {
    $output .= '<div class="description">' . $element['#description'] . "</div>\n";
  }
  $output .= "</div>\n";
  return $output;
}

Comments

Sibiraj PR’s picture

<?php
function <theme_name>_form_element($variables) {
  $element = $variables['element'];
  // Disable radio button N/A
  if ($element['#type'] == 'radio' && $element['#return_value'] === '_none') {
    $variables['element']['#attributes']['disabled'] = TRUE;
  }
  return theme_form_element($variables);
}
?>
GuyPaddock’s picture

I don't see how this would ever work... $variables['element']['#attributes'] is never read by theme_form_element().

diqidoq’s picture

The same with _preprocess_form_element() ... the #attributes array is there (in the $variables array), but empty in final dpm($variables);

Sibiraj PR’s picture

If you're just adding a class to the attributes array a template_preprocess hook would be sufficient, and stop you having to copy the entire thing, e.g.

function MYTHEME_preprocess_form_element(&$vars) {
  $vars['attributes']['class'][] = 'another-class';
}

If you need to add a wrapper around the outer element you can do something like this

function MYTHEME_form_element($vars) {
  $original = theme_form_element($vars);
  return '<div class="something">' . $original . '</div>';
}
kumkum29’s picture

Hello Sibiraj PR,

If I use your code I get a wrapper around the element.
It is possible to place this div inside the element ? (inside the $original)

Thanks.

diqidoq’s picture

@Sibiraj PR:

function MYTHEME_preprocess_form_element(&$vars) {
  $vars['attributes']['class'][] = 'another-class';
}

this will never work. read the comments above ...

drupalstrap’s picture

I am porting Bootstrap themes to Drupal and the forms are a mess because of all of the element wrappers. I need to strip these wrappers out. How can I accomplish that with a preprocess function? Many thanks. Cheers Kevin

schlicki’s picture

Hey guys,
I try to add additional wrappers to form elements to make the label appear in a left column and the field itself in the right one. It all works fine, but I want that for node forms only because 1. all other forms are now messed up and 2. I do not want to influence other custom forms from other modules.
So is there any way to find out if I am in a node form? Just checking the path does not really work because of the overlay for example.
Thanks in advance,
cheers,
j

pglynn’s picture

Give this a shot. Should target all node forms only by hooking into base form that the node edit forms use.

https://api.drupal.org/comment/47958#comment-47958

Mukeysh’s picture

how can i add class if there is error on the form i used thsi but this is not working

if (isset($element['#parents']) && form_get_error($element)) {
    $attributes['class'] = 'error';
  }
randell’s picture

Is is possible to limit the effects of theme_form_element() to the form elements of specific forms only? Form ID doesn't seem to be available from $variables under theme_form_element().

dxx’s picture

Hi, try this:

// add a wrapper around this field and add a attribute class correspond to the ID attribute
function MY_THEME_form_element($vars) {
  $original = theme_form_element($vars);
  if('YOUR_FIELD_NAME' === $vars['element']['#name']){
    return '<div class="'.filter_xss($vars['element']['#id']).'">' . $original . '</div>';
  }
  return $original;
}

Thanks Sibiraj PR!

harora’s picture

Hi,
I have responsive theme and created class to make responsive tables.
Can anyone tell me how to add class to 'tables' in forms ?

Thanks in advance!

nithinkolekar’s picture

landed here from better exposed filter "select options to links" where it invoked this functions and mimicking as filters.

Is there a way or other function to wrap the element inside ul li instead of simple div so that existing list item styles(ex: bootstrap) can be applied?

I got code from https://www.codecademy.com/articles/bootstrap-menus-navbar-modals Step 3: Add Dropdown Items and need to apply to https://www.drupal.org/files/issues/bef-02.png where first four links are simple li items and other subjects should be drop down ul item.