From c62398b372eec4fe7189ac19ccfe6417db0daf81 Mon Sep 17 00:00:00 2001 From: Mark Carver Date: Mon, 17 Apr 2017 03:29:56 -0500 Subject: Issue #2870204 by hass, markcarver: Not properly closing div on bootstrap_image_widget template function --- includes/alter.inc | 45 ++++++++++++++++++++++++++++++++++ includes/process.inc | 5 ++-- templates/image/image-widget.func.php | 8 +----- templates/system/container.func.php | 4 ++- templates/system/form-element.func.php | 20 +++++++++------ 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/includes/alter.inc b/includes/alter.inc index c4a9677..04e2e4f 100644 --- a/includes/alter.inc +++ b/includes/alter.inc @@ -200,6 +200,51 @@ function _bootstrap_element_info_array_merge($info, $cached) { } /** + * Implements hook_field_widget_form_alter(). + */ +function bootstrap_field_widget_form_alter(&$element, &$form_state, $context) { + $widget_type = isset($context['instance']['widget']['type']) ? $context['instance']['widget']['type'] : NULL; + if ($widget_type === 'image_image') { + foreach (element_children($element) as $child) { + $element[$child]['#process'][] = '_bootstrap_image_field_widget_process'; + } + } +} + +/** + * Implements above #process callback. + */ +function _bootstrap_image_field_widget_process($element, &$form_state, $form) { + // Core explicitly sets #theme_wrappers to an empty array for the upload + // element (perhaps for styling reasons?). Thus, bootstrap_form_element() is + // invoked, preventing any necessary logic from executing. To achieve the + // same goal and keep backwards compatibility, reset the theme wrapper back + // and indicating that the wrapper shouldn't be printed. + $element['upload']['#theme_wrappers'][] = 'form_element__image_widget'; + $element['upload']['#form_element_wrapper'] = FALSE; + + // Unfortunately, core also doesn't set #access on the appropriate elements + // until way too late (ironically, because of #ajax). Instead of calling + // file_managed_file_pre_render(), just mimic the same #access logic, but + // using #default_value instead of #value since the ajax request populates + // #value. + $value = empty($element['#default_value']['fid']); + if (!$value) { + $element['upload']['#access'] = FALSE; + $element['upload_button']['#access'] = FALSE; + } + // If we don't already have a file, there is nothing to remove. + else { + $element['remove_button']['#access'] = FALSE; + } + + // Make the upload file element an input group with a button. + $element['upload']['#input_group_button'] = $value; + + return $element; +} + +/** * Implements hook_form_alter(). */ function bootstrap_form_alter(array &$form, array &$form_state = array(), $form_id = NULL) { diff --git a/includes/process.inc b/includes/process.inc index 3a0e05e..4af8e1b 100644 --- a/includes/process.inc +++ b/includes/process.inc @@ -47,14 +47,13 @@ function bootstrap_form_process($element, &$form_state, &$form) { // Ignore buttons before we find the element in the form. $found_current_element = FALSE; - foreach (element_children($parent) as $child) { + foreach (element_children($parent, TRUE) as $child) { if ($parent[$child] === $element) { $found_current_element = TRUE; continue; } - if ($found_current_element && _bootstrap_is_button($parent[$child])) { - _bootstrap_iconize_button($parent[$child]); + if ($found_current_element && _bootstrap_is_button($parent[$child]) && (!isset($parent[$child]['#access']) || !!$parent[$child]['#access'])) { $element['#field_suffix'] = drupal_render($parent[$child]); break; } diff --git a/templates/image/image-widget.func.php b/templates/image/image-widget.func.php index a2f61ba..73f42c3 100644 --- a/templates/image/image-widget.func.php +++ b/templates/image/image-widget.func.php @@ -30,15 +30,9 @@ function bootstrap_image_widget($variables) { } $output .= '
'; diff --git a/templates/system/container.func.php b/templates/system/container.func.php index 22251f7..ad99929 100644 --- a/templates/system/container.func.php +++ b/templates/system/container.func.php @@ -40,7 +40,9 @@ function bootstrap_container($variables) { $element['#attributes']['class'][] = 'form-wrapper'; // Add Bootstrap "form-group" class. - $element['#attributes']['class'][] = 'form-group'; + if (!isset($element['#form_group']) || !!$element['#form_group']) { + $element['#attributes']['class'][] = 'form-group'; + } } return '