Search code examples
jqueryasp.net-mvcrazorjquery-validateunobtrusive-validation

.NET MVC Razor client-side validation not waiting until form submit


I've implemented a .NET MVC form in Razor which uses client-side validation (jquery.validate.js and jquery.validate.unobtrusive.js). My form has a number of different fields that are required and whose format is validated. I'm using data annotations in the model to define this. Eg:

[Required(ErrorMessage = "SSN is required")]
[RegularExpression(@"^\d{3}-\d{2}-\d{4}|\d{9}$", ErrorMessage = "SSN must be in the format 000-00-0000")]
[Display(Name = "SSN")]
public string Ssn { get; set; }

It appears that the default behavior is to validate each form field when it changes. Using the SSN example, as soon as I start typing an SSN, I see an error message saying "SSN must be in the format 000-00-0000". I find this is an invasive/distracting UX since, really, no error has occurred yet; I simply haven't finished entering data.

Is there a way to configure client-side validation to not validate until at least a field has lost focus? Ideally, not until the form has been submitted.

Thanks in advance.

FWIW, here is what my form looks like:

@using (Html.BeginForm("AccountSetup", "Account", FormMethod.Post, new { role = "form", autocomplete = "off" }))
{
    @Html.ValidationSummary(true, "Please correct the error(s) below.")
    <div class="form-group">
        @Html.LabelFor(m => m.SocialSecurityNumber, new { @class = "label-required" })
        @Html.TextBoxFor(m => m.SocialSecurityNumber, new { @class = "form-control", maxlength = 11, data_mask = "000-00-0000" })
        @Html.ValidationMessageFor(m => m.SocialSecurityNumber)
    </div>
}

My web.config has these appsettings:

<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

Solution

  • Thanks to @Sparky's suggestion to look at jQuery validation documentation I found the solution. I added the following javascript to make the form validation behave how I want it to:

    $(document).ready(function () {
        disableResponsiveValidation();
    
        $("#register-form").on('submit', function () {
            enableResponsiveValidation();
        });
    
        function disableResponsiveValidation() {
            var validator = $("#register-form").data("validator");
            if (validator) {
                validator.settings.onkeyup = false;
                validator.settings.onfocusout = false;
            }
        }
    
        function enableResponsiveValidation() {
            var validator = $("#register-form").data("validator");
            if (validator) {
                validator.settings.onkeyup = function (element) {
                    $(element).valid();
                };
                validator.settings.onfocusout = function (element) {
                    $(element).valid();
                };
            }
        }
    });