Skip to content

Commit

Permalink
#97 Implemented delayed validation by introducing delayedValidation o…
Browse files Browse the repository at this point in the history
…ption
  • Loading branch information
Andrew Korshunov committed Aug 8, 2024
1 parent b8b9965 commit a986b63
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ export interface ValidationServiceOptions {
watch: boolean;
root: ParentNode;
addNoValidate: boolean;
delayedValidation: boolean
}

/**
Expand Down Expand Up @@ -1068,6 +1069,15 @@ export class ValidationService {
const cb: ValidationEventCallback = async (event, callback) => {
let validate = this.validators[uid];
if (!validate) return true;

if (
this.options.delayedValidation &&
event && event.type === 'input' &&
!input.classList.contains(this.ValidationInputCssClassName)
) {
// When delayedValidation=true, "input" only takes it back to valid. "Change" can make it invalid.
return;
}

this.logger.log('Validating', { event });
try {
Expand All @@ -1089,9 +1099,19 @@ export class ValidationService {
}, this.debounce);
};

const validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' : 'input';
input.addEventListener(validateEvent, cb.debounced);
cb.remove = () => input.removeEventListener(validateEvent, cb.debounced);
const validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' :
(this.options.delayedValidation ? 'input change' : 'input');
const events = validateEvent.split(' ');

events.forEach((eventName) => {
input.addEventListener(eventName, cb.debounced);
});

cb.remove = () => {
events.forEach((eventName) => {
input.removeEventListener(eventName, cb.debounced);
});
};

this.inputEvents[uid] = cb;
}
Expand Down Expand Up @@ -1378,12 +1398,14 @@ export class ValidationService {
root: document.body,
watch: false,
addNoValidate: true,
delayedValidation: false,
}

/**
* Load default validation providers and scans the entire document when ready.
* @param options.watch If set to true, a MutationObserver will be used to continuously watch for new elements that provide validation directives.
* @param options.addNoValidate If set to true (the default), a novalidate attribute will be added to the containing form in validate elements.
* @param options.delayedValidation If set to false (the default), validation happens while user inputs. If set to true, validation happens on blur, unless input is already invalid, in which case it will validate on input to indicate the value is valid as soon as possible.
*/
bootstrap(options?: Partial<ValidationServiceOptions>) {
Object.assign(this.options, options);
Expand Down

0 comments on commit a986b63

Please sign in to comment.