import { Utility } from '../../core/utility'; 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])'; @Utility({ selector: '[uw-interactive-fieldset]', }) export class InteractiveFieldset { _element; conditionalInput; conditionalValue; target; childInputs; negated; constructor(element) { if (!element) { throw new Error('Interactive Fieldset utility cannot be setup without an element!'); } this._element = element; if (this._element.classList.contains(INTERACTIVE_FIELDSET_INITIALIZED_CLASS)) { return false; } if (this._element.querySelector('[uw-interactive-fieldset]')) { return false; } // param conditionalInput if (!this._element.dataset.conditionalInput) { throw new Error('Interactive Fieldset needs a selector for a conditional input!'); } this.conditionalInput = document.querySelector('#' + this._element.dataset.conditionalInput); if (!this.conditionalInput) { // abort if form has no required inputs throw new Error('Couldn\'t find the conditional input. Aborting setup for interactive fieldset.'); } // param conditionalValue if (!('conditionalValue' in this._element.dataset) && !this._isCheckbox()) { throw new Error('Interactive Fieldset needs a conditional value!'); } this.conditionalValue = this._element.dataset.conditionalValue; this.negated = 'conditionalNegated' in this._element.dataset; this.target = this._element.closest(INTERACTIVE_FIELDSET_UTIL_TARGET_SELECTOR); if (!this.target || this._element.matches(INTERACTIVE_FIELDSET_UTIL_TARGET_SELECTOR)) { this.target = this._element; } this.childInputs = Array.from(this._element.querySelectorAll(INTERACTIVE_FIELDSET_CHILD_SELECTOR)); // add event listener const observer = new MutationObserver(() => this._updateVisibility()); observer.observe(this.conditionalInput, { attributes: true, attributeFilter: ['data-interactive-fieldset-hidden'] }); this.conditionalInput.addEventListener('input', () => this._updateVisibility()); // initial visibility update this._updateVisibility(); // mark as initialized this._element.classList.add(INTERACTIVE_FIELDSET_INITIALIZED_CLASS); } destroy() { // TODO } _updateVisibility() { const active = this._matchesConditionalValue() && !this.conditionalInput.dataset.interactiveFieldsetHidden; this.target.classList.toggle('hidden', !active); this.childInputs.forEach((el) => this._updateChildVisibility(el, active)); } _updateChildVisibility(el, active) { el.disabled = !active; if (active) { delete el.dataset.interactiveFieldsetHidden; } else { el.dataset.interactiveFieldsetHidden = true; } } _matchesConditionalValue() { var matches; if (this._isCheckbox()) { matches = this.conditionalInput.checked === true; } else { matches = this.conditionalInput.value === this.conditionalValue; } if (this.negated) { return !matches; } else { return matches; } } _isCheckbox() { return this.conditionalInput.getAttribute('type') === 'checkbox'; } }