form-element.func.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * @file
  4. * Stub file for bootstrap_form_element().
  5. */
  6. /**
  7. * Returns HTML for a form element.
  8. *
  9. * Each form element is wrapped in a DIV container having the following CSS
  10. * classes:
  11. * - form-item: Generic for all form elements.
  12. * - form-type-#type: The internal element #type.
  13. * - form-item-#name: The internal form element #name (usually derived from the
  14. * $form structure and set via form_builder()).
  15. * - form-disabled: Only set if the form element is #disabled.
  16. *
  17. * In addition to the element itself, the DIV contains a label for the element
  18. * based on the optional #title_display property, and an optional #description.
  19. *
  20. * The optional #title_display property can have these values:
  21. * - before: The label is output before the element. This is the default.
  22. * The label includes the #title and the required marker, if #required.
  23. * - after: The label is output after the element. For example, this is used
  24. * for radio and checkbox #type elements as set in system_element_info().
  25. * If the #title is empty but the field is #required, the label will
  26. * contain only the required marker.
  27. * - invisible: Labels are critical for screen readers to enable them to
  28. * properly navigate through forms but can be visually distracting. This
  29. * property hides the label for everyone except screen readers.
  30. * - attribute: Set the title attribute on the element to create a tooltip
  31. * but output no label element. This is supported only for checkboxes
  32. * and radios in form_pre_render_conditional_form_element(). It is used
  33. * where a visual label is not needed, such as a table of checkboxes where
  34. * the row and column provide the context. The tooltip will include the
  35. * title and required marker.
  36. *
  37. * If the #title property is not set, then the label and any required marker
  38. * will not be output, regardless of the #title_display or #required values.
  39. * This can be useful in cases such as the password_confirm element, which
  40. * creates children elements that have their own labels and required markers,
  41. * but the parent element should have neither. Use this carefully because a
  42. * field without an associated label can cause accessibility challenges.
  43. *
  44. * @param array $variables
  45. * An associative array containing:
  46. * - element: An associative array containing the properties of the element.
  47. * Properties used: #title, #title_display, #description, #id, #required,
  48. * #children, #type, #name.
  49. *
  50. * @return string
  51. * The constructed HTML.
  52. *
  53. * @see theme_form_element()
  54. *
  55. * @ingroup theme_functions
  56. */
  57. function bootstrap_form_element(&$variables) {
  58. $element = &$variables['element'];
  59. $name = !empty($element['#name']) ? $element['#name'] : FALSE;
  60. $type = !empty($element['#type']) ? $element['#type'] : FALSE;
  61. $checkbox = $type && $type === 'checkbox';
  62. $radio = $type && $type === 'radio';
  63. // Create an attributes array for the wrapping container.
  64. if (empty($element['#wrapper_attributes'])) {
  65. $element['#wrapper_attributes'] = array();
  66. }
  67. $wrapper_attributes = &$element['#wrapper_attributes'];
  68. // This function is invoked as theme wrapper, but the rendered form element
  69. // may not necessarily have been processed by form_builder().
  70. $element += array(
  71. '#title_display' => 'before',
  72. );
  73. // Add wrapper ID for 'item' type.
  74. if ($type && $type === 'item' && !empty($element['#markup']) && !empty($element['#id'])) {
  75. $wrapper_attributes['id'] = $element['#id'];
  76. }
  77. // Check for errors and set correct error class.
  78. if ((isset($element['#parents']) && form_get_error($element)) || (!empty($element['#required']) && bootstrap_setting('forms_required_has_error'))) {
  79. $wrapper_attributes['class'][] = 'has-error';
  80. }
  81. // Add necessary classes to wrapper container.
  82. $wrapper_attributes['class'][] = 'form-item';
  83. if ($name) {
  84. $wrapper_attributes['class'][] = 'form-item-' . drupal_html_class($name);
  85. }
  86. if ($type) {
  87. $wrapper_attributes['class'][] = 'form-type-' . drupal_html_class($type);
  88. }
  89. if (!empty($element['#attributes']['disabled'])) {
  90. $wrapper_attributes['class'][] = 'form-disabled';
  91. }
  92. if (!empty($element['#autocomplete_path']) && drupal_valid_path($element['#autocomplete_path'])) {
  93. $wrapper_attributes['class'][] = 'form-autocomplete';
  94. }
  95. // Checkboxes and radios do no receive the 'form-group' class, instead they
  96. // simply have their own classes.
  97. if ($checkbox || $radio) {
  98. $wrapper_attributes['class'][] = drupal_html_class($type);
  99. }
  100. elseif ($type && $type !== 'hidden') {
  101. $wrapper_attributes['class'][] = 'form-group';
  102. }
  103. // Create a render array for the form element.
  104. $build = array(
  105. '#theme_wrappers' => array('container__form_element'),
  106. '#attributes' => $wrapper_attributes,
  107. );
  108. // Render the label for the form element.
  109. $build['label'] = array(
  110. '#markup' => theme('form_element_label', $variables),
  111. );
  112. // Increase the label weight if it should be displayed after the element.
  113. if ($element['#title_display'] === 'after') {
  114. $build['label']['#weight'] = 10;
  115. }
  116. // Checkboxes and radios render the input element inside the label. If the
  117. // element is neither of those, then the input element must be rendered here.
  118. if (!$checkbox && !$radio) {
  119. $prefix = isset($element['#field_prefix']) ? $element['#field_prefix'] : '';
  120. $suffix = isset($element['#field_suffix']) ? $element['#field_suffix'] : '';
  121. if ((!empty($prefix) || !empty($suffix)) && (!empty($element['#input_group']) || !empty($element['#input_group_button']))) {
  122. if (!empty($element['#field_prefix'])) {
  123. $prefix = '<span class="input-group-' . (!empty($element['#input_group_button']) ? 'btn' : 'addon') . '">' . $prefix . '</span>';
  124. }
  125. if (!empty($element['#field_suffix'])) {
  126. $suffix = '<span class="input-group-' . (!empty($element['#input_group_button']) ? 'btn' : 'addon') . '">' . $suffix . '</span>';
  127. }
  128. // Add a wrapping container around the elements.
  129. $input_group_attributes = &_bootstrap_get_attributes($element, 'input_group_attributes');
  130. $input_group_attributes['class'][] = 'input-group';
  131. $prefix = '<div' . drupal_attributes($input_group_attributes) . '>' . $prefix;
  132. $suffix .= '</div>';
  133. }
  134. // Build the form element.
  135. $build['element'] = array(
  136. '#markup' => $element['#children'],
  137. '#prefix' => !empty($prefix) ? $prefix : NULL,
  138. '#suffix' => !empty($suffix) ? $suffix : NULL,
  139. );
  140. }
  141. // Construct the element's description markup.
  142. if (!empty($element['#description'])) {
  143. $build['description'] = array(
  144. '#type' => 'container',
  145. '#attributes' => array(
  146. 'class' => array('help-block'),
  147. ),
  148. '#weight' => 20,
  149. 0 => array('#markup' => filter_xss_admin($element['#description'])),
  150. );
  151. }
  152. // Render the form element build array.
  153. return drupal_render($build);
  154. }