Skip to content

Commit

Permalink
#97 delayed validation is now default behavior as per PR comments. Fi…
Browse files Browse the repository at this point in the history
…xed a bug with data-val-event not being respected
  • Loading branch information
Andrew Korshunov committed Aug 15, 2024
1 parent a59c47a commit 22a1e84
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 49 deletions.
28 changes: 0 additions & 28 deletions Pages/Demos/DelayedValidation.cshtml

This file was deleted.

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>
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.ComponentModel.DataAnnotations;

namespace DemoWeb.Pages.Demos;

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

[BindProperty]
[Required]
[EmailAddress]
public string? AnotherEmailAddress { get; set; }
}
2 changes: 1 addition & 1 deletion Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +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/DelayedValidation">Delayed Validation</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
11 changes: 5 additions & 6 deletions dist/aspnet-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,6 @@ var ValidationService = /** @class */ (function () {
root: document.body,
watch: false,
addNoValidate: true,
delayedValidation: false,
};
/**
* Override CSS class name for input validation error. Default: 'input-validation-error'
Expand Down Expand Up @@ -1080,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 @@ -1097,10 +1097,10 @@ var ValidationService = /** @class */ (function () {
validate = this.validators[uid];
if (!validate)
return [2 /*return*/, true];
if (this.options.delayedValidation &&
if (!input.dataset.valEvent &&
event && event.type === 'input' &&
!input.classList.contains(this.ValidationInputCssClassName)) {
// When delayedValidation=true, "input" only takes it back to valid. "Change" can make it invalid.
// 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 });
Expand All @@ -1127,8 +1127,8 @@ var ValidationService = /** @class */ (function () {
cb(event, callback);
}, _this.debounce);
};
var validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' :
(this.options.delayedValidation ? 'input change' : 'input');
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);
Expand Down Expand Up @@ -1393,7 +1393,6 @@ var ValidationService = /** @class */ (function () {
* 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.
*/
ValidationService.prototype.bootstrap = function (options) {
var _this = this;
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.

11 changes: 4 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,6 @@ export interface ValidationServiceOptions {
watch: boolean;
root: ParentNode;
addNoValidate: boolean;
delayedValidation: boolean
}

/**
Expand Down Expand Up @@ -1071,11 +1070,11 @@ export class ValidationService {
if (!validate) return true;

if (
this.options.delayedValidation &&
!input.dataset.valEvent &&
event && event.type === 'input' &&
!input.classList.contains(this.ValidationInputCssClassName)
) {
// When delayedValidation=true, "input" only takes it back to valid. "Change" can make it invalid.
// 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;
}

Expand All @@ -1099,8 +1098,8 @@ export class ValidationService {
}, this.debounce);
};

const validateEvent = input.dataset.valEvent || input instanceof HTMLSelectElement ? 'change' :
(this.options.delayedValidation ? 'input change' : 'input');
const defaultEvent = input instanceof HTMLSelectElement ? 'change' : 'input change';
const validateEvent = input.dataset.valEvent ?? defaultEvent;
const events = validateEvent.split(' ');

events.forEach((eventName) => {
Expand Down Expand Up @@ -1398,14 +1397,12 @@ 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
2 changes: 0 additions & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ export interface ValidationServiceOptions {
watch: boolean;
root: ParentNode;
addNoValidate: boolean;
delayedValidation: boolean;
}
/**
* Responsible for managing the DOM elements and running the validation providers.
Expand Down Expand Up @@ -336,7 +335,6 @@ export declare class ValidationService {
* 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>): void;
/**
Expand Down

0 comments on commit 22a1e84

Please sign in to comment.