Skip to content

Commit

Permalink
Merge pull request #31 from dahlbyk/form-submit
Browse files Browse the repository at this point in the history
Prevent Recursive Validation
  • Loading branch information
haacked authored Feb 13, 2023
2 parents 4ba3e3a + 4c6e0c3 commit da04d3c
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 46 deletions.
4 changes: 2 additions & 2 deletions Controllers/Validations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ namespace DemoWeb.Controllers;
public class ValidationsController : Controller
{
[HttpPost]
public IActionResult CheckRemote()
public IActionResult CheckRemote(string id)
{
return Ok(false);
return Ok(id == "42");
}

[HttpGet]
Expand Down
2 changes: 1 addition & 1 deletion Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

<script src="/dist/aspnet-validation.js"></script>
<script>
const service = new aspnetValidation.ValidationService();
const service = new aspnetValidation.ValidationService(console);
service.bootstrap();
</script>
</body>
Expand Down
1 change: 1 addition & 0 deletions Pages/Index.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class IndexModel : PageModel
public string? StatusMessage { get; set; }

[BindProperty]
[Display(Name = "Id (42)")]
[Required]
[Remote("CheckRemote", "Validations", HttpMethod = "Post")]
public string? Id { get; set; }
Expand Down
12 changes: 11 additions & 1 deletion dist/aspnet-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,12 @@ var ValidationService = /** @class */ (function () {
if (this.elementEvents[formUID]) {
return;
}
var validating = false;
var cb = function (e, callback) {
// Prevent recursion
if (validating) {
return;
}
if (!_this.shouldValidate(e)) {
return;
}
Expand All @@ -730,7 +735,10 @@ var ValidationService = /** @class */ (function () {
e.preventDefault();
e.stopImmediatePropagation();
}
validating = true;
_this.logger.log('Validating', form);
validate.then(function (success) {
_this.logger.log('Validated (success = %s)', success, form);
var isProgrammaticValidate = !e;
if (success) {
if (isProgrammaticValidate) {
Expand All @@ -756,7 +764,9 @@ var ValidationService = /** @class */ (function () {
_this.focusFirstInvalid(form);
}
}).catch(function (error) {
console.log(error);
_this.logger.log('Validation error', error);
}).finally(function () {
validating = false;
});
};
form.addEventListener('submit', cb);
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.2",
"version": "0.8.3",
"description": "Enables ASP.NET MVC client-side validation, without jQuery!",
"main": "dist/aspnet-validation.js",
"style": "dist/aspnet-validation.css",
Expand Down
63 changes: 36 additions & 27 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface Logger {
}

const nullLogger = new (class implements Logger {
log(_: string, ...args: any[]): void {}
log(_: string, ...args: any[]): void { }
})();

/**
Expand Down Expand Up @@ -685,57 +685,67 @@ export class ValidationService {
return;
}

let validating = false;
let cb = (e: Event, callback?: Function) => {
// Prevent recursion
if (validating) {
return;
}

if (!this.shouldValidate(e)) {
return;
}

let validate = this.getFormValidationTask(formUID);
if (!validate) {
return;
}
}

//Prevent the submit before validation
if (e) {
e.preventDefault();
e.stopImmediatePropagation();
}
//Prevent the submit before validation
if (e) {
e.preventDefault();
e.stopImmediatePropagation();
}

validating = true;
this.logger.log('Validating', form);

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);
{
detail: { valid: true }
});
form.dispatchEvent(validationEvent);

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

return;
}

}

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


if (isProgrammaticValidate) {
callback(false);
}
else {
this.focusFirstInvalid(form);
}
}).catch(error => {
console.log(error);
this.logger.log('Validation error', error);
}).finally(() => {
validating = false;
});
};

Expand Down Expand Up @@ -936,8 +946,7 @@ export class ValidationService {
return async () => {

// only validate visible fields
if (!this.isHidden(input))
{
if (!this.isHidden(input)) {
for (let key in directives) {
let directive = directives[key];
let provider = this.providers[key];
Expand Down Expand Up @@ -986,7 +995,7 @@ export class ValidationService {
* @returns
*/
private isHidden(input: HTMLElement) {
return !(this.allowHiddenFields || input.offsetWidth || input.offsetHeight || input.getClientRects().length );
return !(this.allowHiddenFields || input.offsetWidth || input.offsetHeight || input.getClientRects().length);
}

/**
Expand Down Expand Up @@ -1024,7 +1033,7 @@ export class ValidationService {
}

// If the document is done loading, scan it now.
if(document.readyState === 'complete' || document.readyState === 'interactive') {
if (document.readyState === 'complete' || document.readyState === 'interactive') {
init();
}
else {
Expand Down Expand Up @@ -1061,15 +1070,15 @@ export class ValidationService {
}

private observed(mutation: MutationRecord) {
if(mutation.type === 'childList') {
for(let i = 0; i < mutation.addedNodes.length; i++) {
if (mutation.type === 'childList') {
for (let i = 0; i < mutation.addedNodes.length; i++) {
let node = mutation.addedNodes[i];
this.logger.log('Added node', node);
if (node instanceof HTMLElement) {
this.scan(node);
}
}
} else if(mutation.type === 'attributes') {
} else if (mutation.type === 'attributes') {
if (mutation.target instanceof HTMLElement) {
const oldValue = mutation.oldValue ?? '';
const newValue = mutation.target.attributes[mutation.attributeName]?.value ?? '';
Expand Down
10 changes: 0 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -908,11 +908,6 @@
"resolved" "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz"
"version" "3.5.2"

"[email protected]":
"integrity" "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
"resolved" "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
"version" "1.0.0"

"fill-range@^4.0.0":
"integrity" "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc="
"resolved" "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz"
Expand Down Expand Up @@ -999,11 +994,6 @@
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
"version" "1.0.0"

"fsevents@~2.1.2":
"integrity" "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ=="
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz"
"version" "2.1.3"

"get-caller-file@^2.0.1":
"integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
"resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
Expand Down

0 comments on commit da04d3c

Please sign in to comment.