Skip to content

Commit

Permalink
Make sure input.form exists before accessing it
Browse files Browse the repository at this point in the history
Fixes #47
  • Loading branch information
haacked committed Jul 10, 2023
1 parent 159ba67 commit 1a21a6b
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 31 deletions.
10 changes: 2 additions & 8 deletions DemoWeb.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,10 @@
the target , it would enumerate the files during evaluation, before
the build starts, which may miss files created during the build. -->
<MySourceFiles Include="dist\*.*" />
<Copy
SourceFiles="@(MySourceFiles)"
DestinationFiles="wwwroot\dist\%(RecursiveDir)%(Filename)%(Extension)"
/>
<Copy SourceFiles="@(MySourceFiles)" DestinationFiles="wwwroot\dist\%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<Copy
SourceFiles="@(MySourceFiles)"
DestinationFiles="wwwroot\dist\%(RecursiveDir)%(Filename)%(Extension)"
/>
<Copy SourceFiles="@(MySourceFiles)" DestinationFiles="wwwroot\dist\%(RecursiveDir)%(Filename)%(Extension)" />
</Target>


Expand Down
38 changes: 38 additions & 0 deletions Pages/Demos/RemovedInputs.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@page
@model DemoWeb.Pages.Demos.RemovedInputs

@{
Layout = "Shared/_Layout";
}

<partial name="Shared/_StatusMessage" model="Model.StatusMessage"/>

<fieldset>
<legend>Required ASP.NET Checkboxes with hidden input</legend>

<form method="post">
<div class="form-field">
<p>
This simple test demonstrates that we don't validate removed inputs.
</p>

<div id="value1" class="form-control">
<label>Value 1
<input asp-for="Value1"/>
<span asp-validation-for="Value1"></span>
</label>
</div>

<div id="value2" class="form-control my-1">
<label>Value 2
<input asp-for="Value2"/>
<span asp-validation-for="Value2"></span>
</label>
</div>

<button type="button" onclick="document.getElementById('value2').parentNode.removeChild(document.getElementById('value2'))">Remove Value 2 Input</button>

<input type="submit" value="Input Type Submit" />
</div>
</form>
</fieldset>
26 changes: 26 additions & 0 deletions Pages/Demos/RemovedInputs.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace DemoWeb.Pages.Demos;

public class RemovedInputs : PageModel
{
[TempData]
public string? StatusMessage { get; set; }

[BindProperty]
[Required]
public string? Value1 { get; set; }

[BindProperty]
[Required]
public string? Value2 { get; set; }

public IActionResult OnPost()
{
StatusMessage = "Form was submitted";

return RedirectToPage();
}
}
1 change: 1 addition & 0 deletions Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ul>
<li><a asp-page="Demos/Checkboxes">Checkboxes</a></li>
<li><a asp-page="Demos/SubmitButton">Submit Button</a></li>
<li><a asp-page="Demos/RemovedInputs">Removed Inputs</a></li>
</ul>

@if (Model.StatusMessage != null) {
Expand Down
21 changes: 14 additions & 7 deletions dist/aspnet-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,9 @@ var ValidationService = /** @class */ (function () {
};
// Retrieves the validation span for the input.
ValidationService.prototype.getMessageFor = function (input) {
if (!input.form) {
return [];
}
var formId = this.getElementUID(input.form);
var name = "".concat(formId, ":").concat(input.name);
return this.messageFor[name];
Expand Down Expand Up @@ -1005,10 +1008,12 @@ var ValidationService = /** @class */ (function () {
}
}
this.swapClasses(input, this.ValidationInputCssClassName, this.ValidationInputValidCssClassName);
// Adding an error to one input should also add it to others with the same name (i.e. for radio button and checkbox lists).
var inputs = input.form.querySelectorAll("input[name=\"".concat(input.name, "\"]"));
for (var i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i], this.ValidationInputCssClassName, this.ValidationInputValidCssClassName);
if (input.form) {
// Adding an error to one input should also add it to others with the same name (i.e. for radio button and checkbox lists).
var inputs = input.form.querySelectorAll("input[name=\"".concat(input.name, "\"]"));
for (var i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i], this.ValidationInputCssClassName, this.ValidationInputValidCssClassName);
}
}
var uid = this.getElementUID(input);
this.summary[uid] = message;
Expand All @@ -1028,9 +1033,11 @@ var ValidationService = /** @class */ (function () {
}
this.swapClasses(input, this.ValidationInputValidCssClassName, this.ValidationInputCssClassName);
// Removing an error from one input should also remove it from others with the same name (i.e. for radio button and checkbox lists).
var inputs = input.form.querySelectorAll("input[name=\"".concat(input.name, "\"]"));
for (var i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i], this.ValidationInputValidCssClassName, this.ValidationInputCssClassName);
if (input.form) {
var inputs = input.form.querySelectorAll("input[name=\"".concat(input.name, "\"]"));
for (var i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i], this.ValidationInputValidCssClassName, this.ValidationInputCssClassName);
}
}
var uid = this.getElementUID(input);
delete this.summary[uid];
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.11",
"version": "0.8.12",
"description": "Enables ASP.NET MVC client-side validation, without jQuery!",
"main": "dist/aspnet-validation.js",
"style": "dist/aspnet-validation.css",
Expand Down
30 changes: 19 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,9 @@ export class ValidationService {

// Retrieves the validation span for the input.
private getMessageFor(input: ValidatableElement) {
if (!input.form) {
return [];
}
let formId = this.getElementUID(input.form);
let name = `${formId}:${input.name}`;
return this.messageFor[name];
Expand Down Expand Up @@ -1022,12 +1025,15 @@ export class ValidationService {
this.ValidationInputCssClassName,
this.ValidationInputValidCssClassName);

// Adding an error to one input should also add it to others with the same name (i.e. for radio button and checkbox lists).
const inputs = input.form.querySelectorAll(`input[name="${input.name}"]`);
for (let i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i],
this.ValidationInputCssClassName,
this.ValidationInputValidCssClassName);
if (input.form) {

// Adding an error to one input should also add it to others with the same name (i.e. for radio button and checkbox lists).
const inputs = input.form.querySelectorAll(`input[name="${input.name}"]`);
for (let i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i],
this.ValidationInputCssClassName,
this.ValidationInputValidCssClassName);
}
}

let uid = this.getElementUID(input);
Expand Down Expand Up @@ -1055,11 +1061,13 @@ export class ValidationService {
this.ValidationInputCssClassName);

// Removing an error from one input should also remove it from others with the same name (i.e. for radio button and checkbox lists).
const inputs = input.form.querySelectorAll(`input[name="${input.name}"]`);
for (let i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i],
this.ValidationInputValidCssClassName,
this.ValidationInputCssClassName);
if (input.form) {
const inputs = input.form.querySelectorAll(`input[name="${input.name}"]`);
for (let i = 0; i < inputs.length; i++) {
this.swapClasses(inputs[i],
this.ValidationInputValidCssClassName,
this.ValidationInputCssClassName);
}
}

let uid = this.getElementUID(input);
Expand Down

0 comments on commit 1a21a6b

Please sign in to comment.