Display asp-validation-summary on field change
Asked Answered
S

2

2

Using ASP.NET Core unobtrusive client-side validation, I want to display the validation summary when a field changes, not just on form submit.

The <div asp-validation-summary="All"></div> element displays relevant error messages for each field when the form is submitted, but not when the fields are modified (and the modified state is invalid).

Here is my example code:

My model:

public class InviteNewUser
{

    [DisplayName("Email Address")]
    [Required(ErrorMessage = "Please provide the invitee's Email Address")]
    [EmailAddress(ErrorMessage = "Please provide a valid email address")]
    [StringLength(254, ErrorMessage = "Maximum email address length exceeded")]
    public string EmailAddress { get; set; }

}

My form:

@model InviteNewUser

<form data-ajax="true"
      data-ajax-url="@Url.Action("InviteNewUser","Account")"
      data-ajax-method="POST"
      data-ajax-success="success"
      asp-antiforgery="true">

    <div class="form-group">

        <div class="input-group">
            <div class="input-group-prepend ">
                <label class="input-group-text" asp-for="@Model.EmailAddress">Invitee's Email</label>
            </div>
            <input class="form-control" asp-for="@Model.EmailAddress" />
        </div>

    </div>

    <div asp-validation-summary="All" class="text-danger"></div>

    <button type="submit" class="btn btn-primary">Invite</button>

</form>

@section scripts {

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ajax-unobtrusive/3.2.6/jquery.unobtrusive-ajax.js"></script>

    <script>
        function success() {
            alert("Success!");
        }
    </script>

}

My controller:

    [Authorize]
    public class AccountController : Controller
    {
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> InviteNewUser(InviteNewUser viewModel)
        {
            if (!ModelState.IsValid)
            {
               return View("~/Views/MyForm.cshtml",viewModel);
            }
            return Ok();
        }
    }

So if a user types an invalid email (e.g. zero length, or invalid email format) it should show in the validation summary.

Sexless answered 30/7, 2020 at 0:47 Comment(2)
Did my reply help you solve the problem? If not, please let me know your problem. If it is solved, please accept it as an answer, which will help people with the same problem.Hoy
Sorry I’m on a work break right now I have not had a chance to test either solution but as soon as I can I’ll let you know! And mark the best solution as acceptedSexless
T
2

I had two ideas when I saw this:

  1. Re-use asp-validation-for
  2. Create a custom tag helper, asp-clientside-validation-summary, that is kind of the combination of the existing asp-validation-summary and asp-validation-for.

1. Re-use asp-validation-for

This is the simplest way to achieve what you want.

Basically instead of asp-validaiton-summary, you put each validation message for each field you want to display, generated by asp-validation-for, there and wrap them with a block element. In this way, you don't have to write any custom JavaScript to bind the keyup or change event.

<form asp-area="" asp-controller="user" asp-action="invite"
      data-ajax="true"
      data-ajax-method="POST"
      data-ajax-begin="onBegin"
      data-ajax-complete="onComplete">
    <div class="form-group">
        <label asp-for="EmailAddress"></label>
        <input asp-for="EmailAddress" class="form-control" />
    </div>
    <div class="form-group">
        <label asp-for="DisplayName"></label>
        <input asp-for="DisplayName" class="form-control" />
    </div>
    
    <div class="form-group clientside-validation-summary">
        <span asp-validation-for="EmailAddress" class="text-danger"></span>
        <span asp-validation-for="DisplayName" class="text-danger"></span>
    </div>

    <button type="submit" class="btn btn-primary">Invite</button>
</form>

With a little bit styles, you can make it look like a regular list:

.clientside-validation-summary {
    display: flex;
    flex-flow: column nowrap;

    .field-validation-error > span:before {
        content: "*";
        padding-right: .3rem;
    }
}

Result:

enter image description here

Source code is available at: https://github.com/davidliang2008/DL.NetCore.EmptySolution/commit/c41c4a6a641a8dfb4a5ff14bd2c26c089557f993


2. Create custom tag helper

This would be my preferred way. It seems like I can just re-use/inherit from the existing asp-validation-summary, and add data-val-* attribute on each field it finds for the client side validation.

Unfortunately I haven't gotten it working yet (and I am so busy at work...).

I will update this if I can ever get that working.

Toilette answered 31/7, 2020 at 18:44 Comment(0)
H
1

Using ASP.NET Core unobtrusive client-side validation, I want to display the validation summary when a field changes, not just on form submit.

This can be achieved by judging $("form").valid() in js.

First, we need to add an onkeyup event to the input to trigger verification.

 <input class="form-control" asp-for="@Model.EmailAddress" onkeyup="validateEmail()" />

Then, add validateEmail function in js to judge whether the form verification is valid.

If it is not valid, the validation summary will automatically display the corresponding error message, otherwise, we need to manually delete the error message in validation summary div.

            function validateEmail() {
                if ($("form").valid()) {
                    $("form").find(".validation-summary-errors").html("");
                }
             }

Here is the test result:

enter image description here

Hoy answered 30/7, 2020 at 7:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.