Skip to content

Commit

Permalink
Merge pull request #32 from dahlbyk/handleValidated
Browse files Browse the repository at this point in the history
Extract `handleValidated`
  • Loading branch information
haacked authored Feb 14, 2023
2 parents da04d3c + c3a6e18 commit 4abfdc4
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 61 deletions.
51 changes: 29 additions & 22 deletions dist/aspnet-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,31 @@ var ValidationService = /** @class */ (function () {
var formUID = _this.getElementUID(form);
var formValidationEvent = _this.elementEvents[formUID];
if (formValidationEvent) {
formValidationEvent(null, callback);
formValidationEvent(undefined, callback);
}
};
/**
* Handler for validated form submit events.
* Default calls `submitValidForm(form)` on success
* and `focusFirstInvalid(form)` on failure.
* @param form The form that has been validated.
* @param success The validation result.
*/
this.handleValidated = function (form, success) {
if (success) {
_this.submitValidForm(form);
}
else {
_this.focusFirstInvalid(form);
}
};
/**
* Calls `requestSubmit()` on the provided form.
* @param form The validated form to submit
*/
this.submitValidForm = function (form) {
form.requestSubmit();
};
/**
* Focuses the first invalid element within the provided form
* @param form
Expand Down Expand Up @@ -678,7 +700,7 @@ var ValidationService = /** @class */ (function () {
ValidationService.prototype.getFormValidationTask = function (formUID) {
var formInputUIDs = this.formInputs[formUID];
if (!formInputUIDs || formInputUIDs.length === 0) {
return null;
return Promise.resolve(true);
}
var formValidators = [];
for (var i = 0; i < formInputUIDs.length; i++) {
Expand All @@ -694,7 +716,7 @@ var ValidationService = /** @class */ (function () {
*/
ValidationService.prototype.shouldValidate = function (e) {
// Skip client-side validation if the form has been submitted via a button that has the "formnovalidate" attribute.
return !(e !== null && e['submitter'] && e['submitter']['formNoValidate']);
return !(e && e['submitter'] && e['submitter']['formNoValidate']);
};
/**
* Tracks a <form> element as parent of an input UID. When the form is submitted, attempts to validate the said input asynchronously.
Expand Down Expand Up @@ -739,30 +761,15 @@ var ValidationService = /** @class */ (function () {
_this.logger.log('Validating', form);
validate.then(function (success) {
_this.logger.log('Validated (success = %s)', success, form);
var isProgrammaticValidate = !e;
if (success) {
if (isProgrammaticValidate) {
callback(true);
return;
}
var validationEvent_1 = new CustomEvent('validation', {
detail: { valid: true }
});
form.dispatchEvent(validationEvent_1);
//Resubmit the form here, after the async validation is completed.
form.requestSubmit();
if (callback) {
callback(success);
return;
}
var validationEvent = new CustomEvent('validation', {
detail: { valid: false }
detail: { valid: success }
});
form.dispatchEvent(validationEvent);
if (isProgrammaticValidate) {
callback(false);
}
else {
_this.focusFirstInvalid(form);
}
_this.handleValidated(form, success);
}).catch(function (error) {
_this.logger.log('Validation error', error);
}).finally(function () {
Expand Down
2 changes: 1 addition & 1 deletion dist/aspnet-validation.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/aspnet-validation.min.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aspnet-client-validation",
"version": "0.8.3",
"version": "0.8.4",
"description": "Enables ASP.NET MVC client-side validation, without jQuery!",
"main": "dist/aspnet-validation.js",
"style": "dist/aspnet-validation.css",
Expand Down
72 changes: 41 additions & 31 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export type ValidationDirective = {
*/
export type ValidationProvider = (value: string, element: HTMLInputElement, params: StringKeyValuePair) => boolean | string | Promise<boolean | string>;

/**
* Callback to receive the result of validating a form.
*/
export type ValidatedCallback = (success: boolean) => void;

/**
* A callback method signature that kickstarts a new validation task for an input element, as a Boolean Promise.
*/
Expand Down Expand Up @@ -385,7 +390,7 @@ export class ValidationService {
/**
* A key-value map for element UID to its trigger element (submit event for <form>, input event for <textarea> and <input>).
*/
private elementEvents: { [id: string]: (e: Event, callback?: Function) => any } = {};
private elementEvents: { [id: string]: (e?: Event, callback?: ValidatedCallback) => void } = {};

/**
* A key-value map of input UID to its validation error message.
Expand Down Expand Up @@ -572,7 +577,7 @@ export class ValidationService {
private getFormValidationTask(formUID: string) {
let formInputUIDs = this.formInputs[formUID];
if (!formInputUIDs || formInputUIDs.length === 0) {
return null;
return Promise.resolve(true);
}

let formValidators: Validator[] = [];
Expand All @@ -591,14 +596,37 @@ export class ValidationService {
* @param form
* @param callback
*/
validateForm = (form: HTMLFormElement, callback: Function) => {
validateForm = (form: HTMLFormElement, callback?: ValidatedCallback) => {
let formUID = this.getElementUID(form);
let formValidationEvent = this.elementEvents[formUID];
if (formValidationEvent) {
formValidationEvent(null, callback);
formValidationEvent(undefined, callback);
}
}

/**
* Handler for validated form submit events.
* Default calls `submitValidForm(form)` on success
* and `focusFirstInvalid(form)` on failure.
* @param form The form that has been validated.
* @param success The validation result.
*/
handleValidated = (form: HTMLFormElement, success: boolean) => {
if (success) {
this.submitValidForm(form);
}
else {
this.focusFirstInvalid(form);
}
}

/**
* Calls `requestSubmit()` on the provided form.
* @param form The validated form to submit
*/
submitValidForm = (form: HTMLFormElement) => {
form.requestSubmit();
}

/**
* Focuses the first invalid element within the provided form
Expand All @@ -624,7 +652,7 @@ export class ValidationService {
* @param callback
* @returns
*/
isValid = (form: HTMLFormElement, prevalidate: boolean = true, callback: Function) => {
isValid = (form: HTMLFormElement, prevalidate: boolean = true, callback?: ValidatedCallback) => {
if (prevalidate) {
this.validateForm(form, callback);
}
Expand All @@ -641,7 +669,7 @@ export class ValidationService {
* @param callback
* @returns
*/
isFieldValid = (field: HTMLElement, prevalidate: boolean = true, callback: Function) => {
isFieldValid = (field: HTMLElement, prevalidate: boolean = true, callback?: ValidatedCallback) => {

if (prevalidate) {
let form = field.closest("form");
Expand All @@ -658,9 +686,9 @@ export class ValidationService {
* Returns true if the event triggering the form submission indicates we should validate the form.
* @param e
*/
private shouldValidate(e: Event) {
private shouldValidate(e?: Event) {
// Skip client-side validation if the form has been submitted via a button that has the "formnovalidate" attribute.
return !(e !== null && e['submitter'] && e['submitter']['formNoValidate']);
return !(e && e['submitter'] && e['submitter']['formNoValidate']);
}

/**
Expand All @@ -686,7 +714,7 @@ export class ValidationService {
}

let validating = false;
let cb = (e: Event, callback?: Function) => {
let cb = (e?: Event, callback?: ValidatedCallback) => {
// Prevent recursion
if (validating) {
return;
Expand All @@ -712,36 +740,18 @@ export class ValidationService {

validate.then(success => {
this.logger.log('Validated (success = %s)', success, form);
let isProgrammaticValidate = !e;
if (success) {
if (isProgrammaticValidate) {
callback(true);
return;
}
const validationEvent = new CustomEvent('validation',
{
detail: { valid: true }
});
form.dispatchEvent(validationEvent);

//Resubmit the form here, after the async validation is completed.
form.requestSubmit();

if (callback) {
callback(success);
return;
}

const validationEvent = new CustomEvent('validation',
{
detail: { valid: false }
detail: { valid: success }
});
form.dispatchEvent(validationEvent);

if (isProgrammaticValidate) {
callback(false);
}
else {
this.focusFirstInvalid(form);
}
this.handleValidated(form, success);
}).catch(error => {
this.logger.log('Validation error', error);
}).finally(() => {
Expand Down
23 changes: 20 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export declare type ValidationDirective = {
* Promise return signifies asynchronous plugin behavior, with same behavior as Boolean or String.
*/
export declare type ValidationProvider = (value: string, element: HTMLInputElement, params: StringKeyValuePair) => boolean | string | Promise<boolean | string>;
/**
* Callback to receive the result of validating a form.
*/
export declare type ValidatedCallback = (success: boolean) => void;
/**
* Contains default implementations for ASP.NET Core MVC validation attributes.
*/
Expand Down Expand Up @@ -167,7 +171,20 @@ export declare class ValidationService {
* @param form
* @param callback
*/
validateForm: (form: HTMLFormElement, callback: Function) => void;
validateForm: (form: HTMLFormElement, callback?: ValidatedCallback) => void;
/**
* Handler for validated form submit events.
* Default calls `submitValidForm(form)` on success
* and `focusFirstInvalid(form)` on failure.
* @param form The form that has been validated.
* @param success The validation result.
*/
handleValidated: (form: HTMLFormElement, success: boolean) => void;
/**
* Calls `requestSubmit()` on the provided form.
* @param form The validated form to submit
*/
submitValidForm: (form: HTMLFormElement) => void;
/**
* Focuses the first invalid element within the provided form
* @param form
Expand All @@ -180,15 +197,15 @@ export declare class ValidationService {
* @param callback
* @returns
*/
isValid: (form: HTMLFormElement, prevalidate: boolean, callback: Function) => boolean;
isValid: (form: HTMLFormElement, prevalidate?: boolean, callback?: ValidatedCallback) => boolean;
/**
* Returns true if the provided field is valid, and then calls the callback. The form will be validated before checking, unless prevalidate is set to false
* @param form
* @param prevalidate
* @param callback
* @returns
*/
isFieldValid: (field: HTMLElement, prevalidate: boolean, callback: Function) => boolean;
isFieldValid: (field: HTMLElement, prevalidate?: boolean, callback?: ValidatedCallback) => boolean;
/**
* Returns true if the event triggering the form submission indicates we should validate the form.
* @param e
Expand Down

0 comments on commit 4abfdc4

Please sign in to comment.