From e49e30d8fe5a99fdf2d3f606aa49910bdb992d8c Mon Sep 17 00:00:00 2001 From: Jacob Sutter Date: Fri, 10 Jan 2025 20:43:13 +0000 Subject: [PATCH 1/3] Add manual validation trigger --- README.md | 8 ++++++++ custom-elements.json | 9 +++++++++ src/auto-check-element.ts | 11 +++++++++- test/auto-check.js | 42 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cf3e744..4905662 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,14 @@ input.addEventListener('auto-check-complete', function(event) { [CSRF]: https://en.wikipedia.org/wiki/Cross-site_request_forgery [Response]: https://developer.mozilla.org/en-US/docs/Web/API/Response +## Manually Trigger Validation + +The `triggerValidation()` function can be used to manually tigger the `` element. + +```js +document.getElementById('input-element').closest('auto-check').triggerValidation() +``` + ## Browser support Browsers without native [custom element support][support] require a [polyfill][]. diff --git a/custom-elements.json b/custom-elements.json index 3ab9ad2..fed53b6 100644 --- a/custom-elements.json +++ b/custom-elements.json @@ -155,6 +155,15 @@ "kind": "field", "name": "onloadend" }, + { + "kind": "method", + "name": "triggerValidation", + "return": { + "type": { + "text": "void" + } + } + }, { "kind": "field", "name": "input", diff --git a/src/auto-check-element.ts b/src/auto-check-element.ts index 5f076de..43b316c 100644 --- a/src/auto-check-element.ts +++ b/src/auto-check-element.ts @@ -109,6 +109,7 @@ export class AutoCheckElement extends HTMLElement { input.addEventListener('blur', changeHandler) input.addEventListener('input', changeHandler) + input.addEventListener('triggerValidation', changeHandler) input.autocomplete = 'off' input.spellcheck = false } @@ -134,6 +135,13 @@ export class AutoCheckElement extends HTMLElement { } } + triggerValidation(): void { + const input = this.input + if (!input) return + + input.dispatchEvent(new Event('triggerValidation')) + } + static get observedAttributes(): string[] { return ['required'] } @@ -226,7 +234,8 @@ function handleChange(checker: () => void, event: Event) { autoCheckElement.onlyValidateOnBlur && !autoCheckElement.validateOnKeystroke && autoCheckElement.hasAttribute('dirty')) || // Only validate on blur if only-validate-on-blur is set, input is dirty, and input is not current validating on keystroke - (event.type === 'input' && autoCheckElement.onlyValidateOnBlur && autoCheckElement.validateOnKeystroke) // Only validate on key inputs in only-validate-on-blur mode if validate-on-keystroke is set (when input is invalid) + (event.type === 'input' && autoCheckElement.onlyValidateOnBlur && autoCheckElement.validateOnKeystroke) || // Only validate on key inputs in only-validate-on-blur mode if validate-on-keystroke is set (when input is invalid) + event.type === 'triggerValidation' // Trigger validation manually ) { setLoadingState(event) checker() diff --git a/test/auto-check.js b/test/auto-check.js index 5aecd59..6e82cc5 100644 --- a/test/auto-check.js +++ b/test/auto-check.js @@ -202,6 +202,48 @@ describe('auto-check element', function () { }) }) + describe('manually triggering validation', function () { + let checker + let input + + beforeEach(function () { + const container = document.createElement('div') + container.innerHTML = ` + + + ` + document.body.append(container) + + checker = document.querySelector('auto-check') + input = checker.querySelector('input') + }) + + it('emits on manual trigger', async function () { + const events = [] + input.addEventListener('auto-check-start', event => events.push(event.type)) + + document.getElementById('input-field').closest('auto-check').triggerValidation() + + assert.deepEqual(events, ['auto-check-start']) + }) + + it('does not emit on manual trigger if input is empty', async function () { + const events = [] + input.addEventListener('auto-check-start', event => events.push(event.type)) + + input.value = '' + document.getElementById('input-field').closest('auto-check').triggerValidation() + + assert.deepEqual(events, []) + }) + + afterEach(function () { + document.body.innerHTML = '' + checker = null + input = null + }) + }) + describe('using HTTP GET', function () { let checker let input From ca09d3a31c10f261ad93fdcd706a0d7bc1dcf9b7 Mon Sep 17 00:00:00 2001 From: Jacob Sutter Date: Fri, 10 Jan 2025 15:47:44 -0500 Subject: [PATCH 2/3] Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4905662..fef1819 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ input.addEventListener('auto-check-complete', function(event) { ## Manually Trigger Validation -The `triggerValidation()` function can be used to manually tigger the `` element. +The `triggerValidation()` function can be used to manually trigger the `` element. ```js document.getElementById('input-element').closest('auto-check').triggerValidation() From 46e0a05eb4ee607fc050d064066c49b0f155592d Mon Sep 17 00:00:00 2001 From: Jacob Sutter Date: Fri, 10 Jan 2025 20:54:02 +0000 Subject: [PATCH 3/3] Use CustomEvent and event naming convention --- src/auto-check-element.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/auto-check-element.ts b/src/auto-check-element.ts index 43b316c..c956da7 100644 --- a/src/auto-check-element.ts +++ b/src/auto-check-element.ts @@ -109,7 +109,7 @@ export class AutoCheckElement extends HTMLElement { input.addEventListener('blur', changeHandler) input.addEventListener('input', changeHandler) - input.addEventListener('triggerValidation', changeHandler) + input.addEventListener('triggervalidation', changeHandler) input.autocomplete = 'off' input.spellcheck = false } @@ -139,7 +139,7 @@ export class AutoCheckElement extends HTMLElement { const input = this.input if (!input) return - input.dispatchEvent(new Event('triggerValidation')) + input.dispatchEvent(new CustomEvent('triggervalidation')) } static get observedAttributes(): string[] { @@ -235,7 +235,7 @@ function handleChange(checker: () => void, event: Event) { !autoCheckElement.validateOnKeystroke && autoCheckElement.hasAttribute('dirty')) || // Only validate on blur if only-validate-on-blur is set, input is dirty, and input is not current validating on keystroke (event.type === 'input' && autoCheckElement.onlyValidateOnBlur && autoCheckElement.validateOnKeystroke) || // Only validate on key inputs in only-validate-on-blur mode if validate-on-keystroke is set (when input is invalid) - event.type === 'triggerValidation' // Trigger validation manually + event.type === 'triggervalidation' // Trigger validation manually ) { setLoadingState(event) checker()