Skip to content

Commit

Permalink
Merge pull request #119 from andkorsh/main
Browse files Browse the repository at this point in the history
#97 Implemented delayed validation by introducing delayedValidation o…
  • Loading branch information
haacked authored Aug 16, 2024
2 parents b8b9965 + 22a1e84 commit 746a8a9
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 8 deletions.
35 changes: 35 additions & 0 deletions Pages/Demos/ImmediateValidation.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@page
@model DemoWeb.Pages.Demos.ImmediateValidation
@{
Layout = "Shared/_Layout";
}

<div asp-validation-summary="All">
<span>Please correct the following errors</span>
</div>

<fieldset>
<legend>Required Email input with data-val-event specified for immediate validation as you type.</legend>
<form method="post">
<legend>Input with immediate validation (<code>data-val-event="input"</code>)</legend>
<div class="form-field">
<label asp-for="EmailAddress"></label>
<input asp-for="EmailAddress" data-val-event="input" />
<span asp-validation-for="EmailAddress"></span>
</div>
<legend>Input with default behavior</legend>
<div class="form-field">
<label asp-for="AnotherEmailAddress"></label>
<input asp-for="AnotherEmailAddress" />
<span asp-validation-for="AnotherEmailAddress"></span>
</div>
<input type="submit" value="Submit"/>
</form>
</fieldset>

@section Scripts {
<script>
const service = new aspnetValidation.ValidationService(console);
service.bootstrap();
</script>
}
18 changes: 18 additions & 0 deletions Pages/Demos/ImmediateValidation.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;

namespace DemoWeb.Pages.Demos;

public class ImmediateValidation : PageModel
{
[BindProperty]
[Required]
[EmailAddress]
public string? EmailAddress { get; set; }

[BindProperty]
[Required]
[EmailAddress]
public string? AnotherEmailAddress { get; set; }
}
1 change: 1 addition & 0 deletions Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<li><a asp-page="Demos/FormAction">Form Action</a></li>
<li><a asp-page="Demos/DisabledInputsWithWatch">Disabled inputs (<code>{watch: true}</code>)</a></li>
<li><a asp-page="Demos/DisabledInputsNoWatch">Disabled inputs (no watch)</a></li>
<li><a asp-page="Demos/ImmediateValidation">Immediate Validation (<code>data-val-event="input"</code>)</a></li>
</ul>

@if (Model.StatusMessage != null) {
Expand Down
21 changes: 18 additions & 3 deletions dist/aspnet-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,7 @@ var ValidationService = /** @class */ (function () {
*/
ValidationService.prototype.addInput = function (input) {
var _this = this;
var _a;
var uid = this.getElementUID(input);
var directives = this.parseDirectives(input.attributes);
this.validators[uid] = this.createValidator(input, directives);
Expand All @@ -1096,6 +1097,12 @@ var ValidationService = /** @class */ (function () {
validate = this.validators[uid];
if (!validate)
return [2 /*return*/, true];
if (!input.dataset.valEvent &&
event && event.type === 'input' &&
!input.classList.contains(this.ValidationInputCssClassName)) {
// When no data-val-event specified on a field, "input" event only takes it back to valid. "Change" event can make it invalid.
return [2 /*return*/, true];
}
this.logger.log('Validating', { event: event });
_a.label = 1;
case 1:
Expand All @@ -1120,9 +1127,17 @@ var ValidationService = /** @class */ (function () {
cb(event, callback);
}, _this.debounce);
};
var validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' : 'input';
input.addEventListener(validateEvent, cb.debounced);
cb.remove = function () { return input.removeEventListener(validateEvent, cb.debounced); };
var defaultEvent = input instanceof HTMLSelectElement ? 'change' : 'input change';
var validateEvent = (_a = input.dataset.valEvent) !== null && _a !== void 0 ? _a : defaultEvent;
var events = validateEvent.split(' ');
events.forEach(function (eventName) {
input.addEventListener(eventName, cb.debounced);
});
cb.remove = function () {
events.forEach(function (eventName) {
input.removeEventListener(eventName, cb.debounced);
});
};
this.inputEvents[uid] = cb;
};
ValidationService.prototype.removeInput = function (input) {
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.

25 changes: 22 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,15 @@ export class ValidationService {
const cb: ValidationEventCallback = async (event, callback) => {
let validate = this.validators[uid];
if (!validate) return true;

if (
!input.dataset.valEvent &&
event && event.type === 'input' &&
!input.classList.contains(this.ValidationInputCssClassName)
) {
// When no data-val-event specified on a field, "input" event only takes it back to valid. "Change" event can make it invalid.
return true;
}

this.logger.log('Validating', { event });
try {
Expand All @@ -1089,9 +1098,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 defaultEvent = input instanceof HTMLSelectElement ? 'change' : 'input change';
const validateEvent = input.dataset.valEvent ?? defaultEvent;
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

0 comments on commit 746a8a9

Please sign in to comment.