UNPKG

bootstrap-italia

Version:

Bootstrap Italia è un tema Bootstrap 5 per la creazione di applicazioni web nel pieno rispetto delle linee guida di design per i siti internet e i servizi digitali della PA

201 lines (181 loc) 5.92 kB
import JustValidate from 'just-validate'; import { CssClassObserver, ContentObserver } from './util/observer.js'; /** * -------------------------------------------------------------------------- * Bootstrap Italia (https://italia.github.io/bootstrap-italia/) * Authors: https://github.com/italia/bootstrap-italia/blob/main/AUTHORS * Licensed under BSD-3-Clause license (https://github.com/italia/bootstrap-italia/blob/main/LICENSE) * -------------------------------------------------------------------------- */ const CONFIG_DEFAULT = { errorFieldCssClass: 'is-invalid', errorLabelCssClass: 'just-validate-error-label', }; const NAME = 'justvalidatebi'; const CLASS_NAME_SRONLY = 'sr-only-justvalidate-bi'; const SELECTOR_SPAN_SRONLY = `.${CLASS_NAME_SRONLY}`; class FormValidate { constructor(selector, config, dictLocale) { this.formSelector = selector; if (typeof window === 'undefined' || typeof document === 'undefined') { return } this.target = document.querySelector(selector); if (dictLocale != undefined) this.validate = new JustValidate(selector, config, dictLocale); else { this.validate = new JustValidate(selector, config); } this.config = Object.assign({}, CONFIG_DEFAULT, this.validate.globalConfig); this.formItems = []; this.init(); return this.validate } init() { const inputs = this.target.querySelectorAll('input, select'); inputs.forEach((input) => { const watcher = new CssClassObserver( input, this.config.errorFieldCssClass, () => this.onInputError(input), () => this.onInputErrorRemove(input), true ); if (!input.id) { input.setAttribute('id', NAME + '-input-' + Math.random()); } this.formItems.push({ item: input, watcher, }); }); const fieldsets = this.target.querySelectorAll('fieldset'); fieldsets.forEach((field) => { const inputs = field.querySelectorAll('input[type=radio],input[type=checkbox]'); if (inputs.length > 0) { const watcher = new ContentObserver( field, '.' + this.config.errorLabelCssClass, () => this.onFieldsetError(field), () => this.onFieldsetErrorRemove(field) ); if (!field.id) { field.setAttribute('id', NAME + '-fieldset-' + Math.random()); } this.formItems.push({ item: field, watcher, }); } }); } /** * Adds ARIA attributes to the input and to the error message * @param {Object} target - the input element */ onInputError(target) { const errElements = this.getErrorMessages(target); const errIds = []; errElements.forEach((el, idx) => { const id = target.id + '-error-' + idx; el.setAttribute('id', id); errIds.push(id); }); if (errIds.length > 0) { target.setAttribute('aria-describedby', errIds.join(' ')); target.setAttribute('aria-invalid', 'true'); } /*else { console.warn('[JustValidateIt] the element is invalid but no error message was found', { target }) }*/ } /** * Removes input ARIA attributes * @param {Object} target - the input element */ onInputErrorRemove(target) { target.removeAttribute('aria-describedby'); target.setAttribute('aria-invalid', 'false'); } /** * Adds ARIA attributes to the fieldset and to the error message * @param {Object} target - the fieldset element */ onFieldsetError(target) { const errElements = this.getErrorMessages(target); const errIds = []; const errTexts = []; errElements.forEach((el, idx) => { const id = target.id + '-error-' + idx; el.setAttribute('id', id); errIds.push(id); errTexts.push(el.textContent); }); if (errIds.length > 0) { const legend = target.querySelector('legend'); if (legend) { legend.setAttribute('aria-describedby', errIds.join(' ')); legend.setAttribute('aria-invalid', 'true'); } } } /** * Removes the fieldset ARIA attributes * @param {Object} target - the fieldset element */ onFieldsetErrorRemove(target) { const legend = target.querySelector('legend'); if (legend) { legend.removeAttribute('aria-describedby'); legend.setAttribute('aria-invalid', 'false'); const span = legend.querySelector(SELECTOR_SPAN_SRONLY); if (span) { span.remove(); } } } /** * get the error messages for the target * @param {Object} target - target node */ getErrorMessages(target) { let parent = target; let messages = parent.querySelectorAll('.' + this.config.errorLabelCssClass); while (parent != null && messages.length === 0) { parent = parent.parentNode; messages = parent.querySelectorAll('.' + this.config.errorLabelCssClass); } return messages } } //Plugins /** * Validate a custom autocomplete select * @param {string} inputId - the input id * @param {Object} config - { required } */ const ValidatorSelectAutocomplete = (inputId, config = {}) => { return (value, fields) => { let result = false; const field = fields[inputId]; if (field) { if (!config.required && !value) { result = true; } else { if (typeof window !== 'undefined' && typeof document !== 'undefined') { document .querySelector('#' + field.elem.id + '-select') .querySelectorAll('option') .forEach((option) => { if (option.text === value) { result = true; } }); } } } else { throw new Error('ValidatorSelectAutocomplete: ' + inputId + ' not found as form field') } return result } }; export { FormValidate, ValidatorSelectAutocomplete }; //# sourceMappingURL=form-validate.js.map