From 65b429a320b6876a7d72d40935a7d49257ef77d7 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Tue, 5 May 2020 16:23:49 +0200 Subject: [PATCH] fix(interactive-fieldset): fix behaviour for nested fieldsets --- .../src/utils/form/interactive-fieldset.js | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/frontend/src/utils/form/interactive-fieldset.js b/frontend/src/utils/form/interactive-fieldset.js index 9ba364470..438e41012 100644 --- a/frontend/src/utils/form/interactive-fieldset.js +++ b/frontend/src/utils/form/interactive-fieldset.js @@ -5,10 +5,13 @@ const INTERACTIVE_FIELDSET_UTIL_TARGET_SELECTOR = '.interactive-fieldset__target const INTERACTIVE_FIELDSET_INITIALIZED_CLASS = 'interactive-fieldset--initialized'; const INTERACTIVE_FIELDSET_CHILD_SELECTOR = 'input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled])'; +let fieldsetCounter = 0; + @Utility({ selector: '[uw-interactive-fieldset]', }) export class InteractiveFieldset { + fieldsetIdent = (fieldsetCounter++).toString(); _element; @@ -56,21 +59,23 @@ export class InteractiveFieldset { this.target = this._element; } - this.childInputs = Array.from(this._element.querySelectorAll(INTERACTIVE_FIELDSET_CHILD_SELECTOR)); + this.childInputs = Array.from(this._element.querySelectorAll(INTERACTIVE_FIELDSET_CHILD_SELECTOR)).filter(child => child.closest('[uw-interactive-fieldset]') === this._element); // add event listener - const observer = new MutationObserver(() => this._updateVisibility()); + const observer = new MutationObserver(this._updateVisibility.bind(this)); observer.observe(this.conditionalInput, { attributes: true, attributeFilter: ['data-interactive-fieldset-hidden'] }); - this.conditionalInput.addEventListener('input', () => this._updateVisibility()); - - // initial visibility update - this._updateVisibility(); + this.conditionalInput.addEventListener('input', this._updateVisibility.bind(this)); // mark as initialized this._element.classList.add(INTERACTIVE_FIELDSET_INITIALIZED_CLASS); } + start() { + // initial visibility update + this._updateVisibility(); + } + destroy() { // TODO } @@ -78,7 +83,20 @@ export class InteractiveFieldset { _updateVisibility() { const active = this._matchesConditionalValue() && !this.conditionalInput.dataset.interactiveFieldsetHidden; - this.target.classList.toggle('hidden', !active); + let hiddenBy = (this.target.dataset.interactiveFieldsetHiddenBy || '').split(',').filter(str => str.length !== 0); + + if (active) + hiddenBy = hiddenBy.filter(ident => ident !== this.fieldsetIdent); + else if (hiddenBy.every(ident => ident !== this.fieldsetIdent)) + hiddenBy = [ ...hiddenBy, this.fieldsetIdent ]; + + if (hiddenBy.length !== 0) { + this.target.dataset.interactiveFieldsetHiddenBy = hiddenBy.join(','); + this.target.classList.add('hidden'); + } else { + delete this.target.dataset['interactiveFieldsetHiddenBy']; + this.target.classList.remove('hidden'); + } this.childInputs.forEach((el) => this._updateChildVisibility(el, active)); }