From 80e996a281af2eb23e7aba40b098c2dd8857ffb7 Mon Sep 17 00:00:00 2001 From: Dan Remollino Date: Mon, 7 Apr 2025 01:22:09 -0400 Subject: [PATCH] updated handling of checkboxes --- index.html | 4 +-- validation.js | 77 +++++++++++++++++++++------------------------------ 2 files changed, 33 insertions(+), 48 deletions(-) diff --git a/index.html b/index.html index 55b2a6b..457f977 100644 --- a/index.html +++ b/index.html @@ -58,11 +58,11 @@
Check Group - + - + diff --git a/validation.js b/validation.js index 367b75a..ca4fe1e 100644 --- a/validation.js +++ b/validation.js @@ -7,7 +7,7 @@ class ValidationField { maxCount = null message = null messageOutputted = null - minCount = null + minCount = 1 optional = false pattern = null patternMessage = null @@ -95,24 +95,6 @@ class ValidationField { // add a native pattern attr if pattern property is present if (this.pattern) this.el.setAttribute('pattern', this.pattern) - // track minimum selections for checkboxes; todo: add multiple attr support - if (this.el.type === 'checkbox') { - if (!this.validationInstance.multi.hasOwnProperty(this.el.name)) { - this.validationInstance.multi[this.el.name] = {} - // this.validationInstance.multi[this.el.name].count = 0 - this.validationInstance.multi[this.el.name].minCount = this.minCount ?? 1 - if (this.maxCount) this.validationInstance.multi[this.el.name].maxCount = this.maxCount - } - - // if (this.el.checked) this.validationInstance.multi[this.el.name].count++ - - // this.el.addEventListener('change', () => { - // this.el.checked - // ? this.validationInstance.multi[this.el.name].count++ - // : this.validationInstance.multi[this.el.name].count-- - // }) - } - // add required indicator if (this.validationInstance.reqIndicators) { const hasIndicator = this.formGroupEl?.querySelector(`.${this.validationInstance.reqIndicatorClass}`) @@ -141,7 +123,6 @@ class Validation { form = null invalidClass = 'invalid' messageClass = 'invalid__message' - multi = [] onlyOnSubmit = false onSuccess = null passConfirm = true @@ -221,19 +202,21 @@ class Validation { for (const nameAttr of this.reqData) { const fields = this.form.querySelectorAll(`[name="${nameAttr}"]:where(input, select, textarea)`) for (const el of fields) { + // checkbox specfic + if (el.type === 'checkbox') { + // combine all data-validation attrs and copy to all checks in the group + const checks = this.form.querySelectorAll(`input[name="${el.name}"]`) + let multiOptions = {} + for (const check of checks) { + Object.assign(multiOptions, check.dataset.validation ? JSON.parse(check.dataset.validation) : {}) + el.dataset.validation = JSON.stringify(multiOptions) + } + } + this.reqFields.push(new ValidationField({el: el, validationInstance: this})) } } - this.form.addEventListener('submit', e => { - e.preventDefault() - this.validate() - }) - - this.form.addEventListener('reset', () => { - this.removeErrors() - }) - // add/remove a field when disabled attr is dynamically toggled const observeEls = this.form.querySelectorAll('input, select, textarea, [data-validation]:not(form, input, select, textarea)') const disabledObserver = new MutationObserver((mutationList, observer) => { @@ -260,6 +243,15 @@ class Validation { }) } + this.form.addEventListener('submit', e => { + e.preventDefault() + this.validate() + }) + + this.form.addEventListener('reset', () => { + this.removeErrors() + }) + // console.log(this) } @@ -331,23 +323,16 @@ class Validation { validateCheckbox(fieldInstance, nameAttrVal) { const checkCount = this.form.querySelectorAll(`[name="${nameAttrVal}"]:checked`).length - - // minCount only - if (!fieldInstance.validationInstance.multi[`${nameAttrVal}`].hasOwnProperty('maxCount')) { - if (checkCount < fieldInstance.validationInstance.multi[`${nameAttrVal}`].minCount) { - let messageMod = fieldInstance.validationInstance.multi[`${nameAttrVal}`].minCount === 1 ? `choice is` : `choices are` - let message = `At least ${fieldInstance.validationInstance.multi[`${nameAttrVal}`].minCount} ${messageMod} required.` - this.addError(fieldInstance, message) - } - } - - // minCount and maxCount set - if (fieldInstance.validationInstance.multi[`${nameAttrVal}`].maxCount) { - if (checkCount < fieldInstance.validationInstance.multi[`${nameAttrVal}`].minCount || - checkCount > fieldInstance.validationInstance.multi[`${nameAttrVal}`].maxCount) { - let message = `At least ${fieldInstance.validationInstance.multi[`${nameAttrVal}`].minCount}, and no more than ${fieldInstance.validationInstance.multi[`${nameAttrVal}`].maxCount} choices are required.` - this.addError(fieldInstance, message) - } + let message + if (fieldInstance.maxCount && (checkCount < fieldInstance.minCount || checkCount > fieldInstance.maxCount)) { + message = fieldInstance.minCount !== fieldInstance.maxCount + ? `At least ${fieldInstance.minCount}, and no more than ${fieldInstance.maxCount} choices are required.` + : `${fieldInstance.minCount} choices are required.` + this.addError(fieldInstance, message) + } else if (checkCount < fieldInstance.minCount) { + let messageMod = fieldInstance.minCount === 1 ? `choice is` : `choices are` + message = `At least ${fieldInstance.minCount} ${messageMod} required.` + this.addError(fieldInstance, message) } }