Skip to content

Commit a59c47a

Browse files
author
Andrew Korshunov
committed
#97 Delayed Validation Sample
1 parent a986b63 commit a59c47a

File tree

8 files changed

+67
-6
lines changed

8 files changed

+67
-6
lines changed

Pages/Demos/DelayedValidation.cshtml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
@page
2+
@model DemoWeb.Pages.Demos.DelayedValidation
3+
@{
4+
Layout = "Shared/_Layout";
5+
}
6+
7+
<div asp-validation-summary="All">
8+
<span>Please correct the following errors</span>
9+
</div>
10+
11+
<fieldset>
12+
<legend>Required Email input with delayed validation.</legend>
13+
<form method="post">
14+
<div class="form-field">
15+
<label asp-for="EmailAddress"></label>
16+
<input asp-for="EmailAddress" />
17+
<span asp-validation-for="EmailAddress"></span>
18+
</div>
19+
<input type="submit" value="Submit"/>
20+
</form>
21+
</fieldset>
22+
23+
@section Scripts {
24+
<script>
25+
const service = new aspnetValidation.ValidationService(console);
26+
service.bootstrap({ delayedValidation: true });
27+
</script>
28+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.AspNetCore.Mvc.RazorPages;
4+
using Microsoft.AspNetCore.Mvc.Rendering;
5+
6+
namespace DemoWeb.Pages.Demos;
7+
8+
public class DelayedValidation : PageModel
9+
{
10+
[BindProperty]
11+
[Required]
12+
[EmailAddress]
13+
public string? EmailAddress { get; set; }
14+
}

Pages/Index.cshtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<li><a asp-page="Demos/FormAction">Form Action</a></li>
1515
<li><a asp-page="Demos/DisabledInputsWithWatch">Disabled inputs (<code>{watch: true}</code>)</a></li>
1616
<li><a asp-page="Demos/DisabledInputsNoWatch">Disabled inputs (no watch)</a></li>
17+
<li><a asp-page="Demos/DelayedValidation">Delayed Validation</a></li>
1718
</ul>
1819

1920
@if (Model.StatusMessage != null) {

dist/aspnet-validation.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ var ValidationService = /** @class */ (function () {
690690
root: document.body,
691691
watch: false,
692692
addNoValidate: true,
693+
delayedValidation: false,
693694
};
694695
/**
695696
* Override CSS class name for input validation error. Default: 'input-validation-error'
@@ -1096,6 +1097,12 @@ var ValidationService = /** @class */ (function () {
10961097
validate = this.validators[uid];
10971098
if (!validate)
10981099
return [2 /*return*/, true];
1100+
if (this.options.delayedValidation &&
1101+
event && event.type === 'input' &&
1102+
!input.classList.contains(this.ValidationInputCssClassName)) {
1103+
// When delayedValidation=true, "input" only takes it back to valid. "Change" can make it invalid.
1104+
return [2 /*return*/, true];
1105+
}
10991106
this.logger.log('Validating', { event: event });
11001107
_a.label = 1;
11011108
case 1:
@@ -1120,9 +1127,17 @@ var ValidationService = /** @class */ (function () {
11201127
cb(event, callback);
11211128
}, _this.debounce);
11221129
};
1123-
var validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' : 'input';
1124-
input.addEventListener(validateEvent, cb.debounced);
1125-
cb.remove = function () { return input.removeEventListener(validateEvent, cb.debounced); };
1130+
var validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' :
1131+
(this.options.delayedValidation ? 'input change' : 'input');
1132+
var events = validateEvent.split(' ');
1133+
events.forEach(function (eventName) {
1134+
input.addEventListener(eventName, cb.debounced);
1135+
});
1136+
cb.remove = function () {
1137+
events.forEach(function (eventName) {
1138+
input.removeEventListener(eventName, cb.debounced);
1139+
});
1140+
};
11261141
this.inputEvents[uid] = cb;
11271142
};
11281143
ValidationService.prototype.removeInput = function (input) {
@@ -1378,6 +1393,7 @@ var ValidationService = /** @class */ (function () {
13781393
* Load default validation providers and scans the entire document when ready.
13791394
* @param options.watch If set to true, a MutationObserver will be used to continuously watch for new elements that provide validation directives.
13801395
* @param options.addNoValidate If set to true (the default), a novalidate attribute will be added to the containing form in validate elements.
1396+
* @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.
13811397
*/
13821398
ValidationService.prototype.bootstrap = function (options) {
13831399
var _this = this;

dist/aspnet-validation.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/aspnet-validation.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ export class ValidationService {
10761076
!input.classList.contains(this.ValidationInputCssClassName)
10771077
) {
10781078
// When delayedValidation=true, "input" only takes it back to valid. "Change" can make it invalid.
1079-
return;
1079+
return true;
10801080
}
10811081

10821082
this.logger.log('Validating', { event });

types/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export interface ValidationServiceOptions {
9999
watch: boolean;
100100
root: ParentNode;
101101
addNoValidate: boolean;
102+
delayedValidation: boolean;
102103
}
103104
/**
104105
* Responsible for managing the DOM elements and running the validation providers.
@@ -335,6 +336,7 @@ export declare class ValidationService {
335336
* Load default validation providers and scans the entire document when ready.
336337
* @param options.watch If set to true, a MutationObserver will be used to continuously watch for new elements that provide validation directives.
337338
* @param options.addNoValidate If set to true (the default), a novalidate attribute will be added to the containing form in validate elements.
339+
* @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.
338340
*/
339341
bootstrap(options?: Partial<ValidationServiceOptions>): void;
340342
/**

0 commit comments

Comments
 (0)