From 2f5e12c495b6702c53f5d308f1a54e51689722c0 Mon Sep 17 00:00:00 2001 From: orakili Date: Wed, 10 Apr 2024 21:25:49 +0000 Subject: [PATCH] fix: replace non-working Drupal form state logic with custom one to show/hide the OCHA product field when OCHA is selected Refs: RW-934 --- .../src/Services/ReportFormAlter.php | 38 ++++++------------- .../reliefweb_form/js/widget.autocomplete.js | 25 ++++++++++++ 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php b/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php index c5546f64d..be44f632c 100644 --- a/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php +++ b/html/modules/custom/reliefweb_entities/src/Services/ReportFormAlter.php @@ -249,10 +249,21 @@ public function validateOriginFields(array $form, FormStateInterface &$form_stat * Ensure only 1 OCHA product is selectable and that it's mandatory when OCHA * is selected as source or hidden otherwise. * + * Note: the OCHA product field is only displayed when OCHA is selected, in + * which case the field is also marked as required. This is handled by the + * `reliefweb_form/widget.autocomplete` library in the `handleSources()` + * function because Drupal form states don't provide a way to apply a state + * when a value is among a list of selected values. Only exact matchs are + * supported in Drupal 10.2.5. + * * @param array $form * Form to alter. * @param \Drupal\Core\Form\FormStateInterface $form_state * Form state. + * + * @see https://www.drupal.org/project/drupal/issues/1149078 + * @see https://humanitarian.atlassian.net/browse/RW-934 + * @see reliefweb_form/widget.autocomplete */ protected function alterOchaProductField(array &$form, FormStateInterface $form_state) { $widget = &$form['field_ocha_product']['widget']; @@ -264,33 +275,6 @@ protected function alterOchaProductField(array &$form, FormStateInterface $form_ FormHelper::removeOptions($form, 'field_ocha_product', [12351]); } - /* Temporarily disabled on 2024/04/12. - * - * The changes from https://www.drupal.org/project/drupal/issues/1149078 - * are not compatible with the way "reliefweb_form/drupal.states" compared - * values in the array. - * Drupal checks exact match between the values of the state condition and - * the selected values of the form element while our library was just - * checking that the values of the state condition were in the list of the - * selected values. - * Drupal doesn't currently have a way to handle this use case so to avoid - * issues we always display the OCHA product field. - * It's ignored when OCHA is not one of the selected sources and is - * mandatory if selected. - * - * @see ::validateOchaProductField() - * - * // Only display the OCHA product when OCHA is selected. - * $condition = [ - * 'select[name="field_source[]"]' => ['value' => ['1503']], - * ]; - * // We put the visibility state on the container to avoid styling issues - * // with the surrounding elements but we need to to put the required state - * // on the widget element for it to work properly. - * $form['field_ocha_product']['#states']['visible'] = $condition; - * $widget['#states']['required'] = $condition; - */ - // Remove the empty option. unset($widget['#options']['_none']); diff --git a/html/modules/custom/reliefweb_form/js/widget.autocomplete.js b/html/modules/custom/reliefweb_form/js/widget.autocomplete.js index 95f5aacd9..b70983eee 100644 --- a/html/modules/custom/reliefweb_form/js/widget.autocomplete.js +++ b/html/modules/custom/reliefweb_form/js/widget.autocomplete.js @@ -450,12 +450,37 @@ // Retrieve the list of selected sources without an already loaded // attention message. var selected = []; + var ochaSelected = false; var options = sourceElement.getElementsByTagName('option'); for (var i = 0, l = options.length; i < l; i++) { var option = options[i]; if (option.selected && !option.hasAttribute('data-message')) { selected.push(option.value); } + // Check if OCHA (id 1503) is selected. + if (option.selected && option.value == 1503) { + ochaSelected = true; + } + } + + // Show/hide the OCHA product field based on whether OCHA is selected + // as source or not. We cannot use Drupal form states for that because + // they don't provide a way to apply a state when a value in among a + // list of selected values. Only exact matches are supported in Drupal + // 10.2.5. + // @see https://www.drupal.org/project/drupal/issues/1149078 + // @see https://humanitarian.atlassian.net/browse/RW-934 + var ochaProduct = document.querySelector('[data-drupal-selector="edit-field-ocha-product-wrapper"]'); + if (ochaProduct) { + var ochaProductOptional = ochaProduct.querySelector('.form-optional'); + if (ochaSelected) { + ochaProduct.removeAttribute('hidden'); + ochaProductOptional.setAttribute('hidden', ''); + } + else { + ochaProduct.setAttribute('hidden', ''); + ochaProductOptional.removeAttribute('hidden'); + } } // Fetch the new data if there are selected sources.