Unobtrusive Client side validation in MVC4 not working
Asked Answered
L

6

11

I have layout page with all scripts as shown below.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>My Site</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <some custom css>
    <modernizr>
    <script src="~/Scripts/Jquery/jquery-1.9.1.js"></script>
    <script src="~/Scripts/Jquery/jquery-ui-1.10.2.js"></script>
    <script src="~/Scripts/Jquery/jquery.unobtrusive-ajax.js"></script>
    <script src="~/Scripts/Jquery/jquery.validate.js"></script>
    <script src="~/Scripts/Jquery/jquery.validate.unobtrusive.js"></script>
    <some custom scripts>
    <bootstrap scripts>
    <knockout scripts>           
</head>
<body>
  @RenderBody()
</body>
</html>

Then I have my registration Form as shown

@model Mysite.Models.Account.Account
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "register" }))
{
 @Html.AntiForgeryToken();
 <h1>Login</h1>
 @Html.ValidationSummary();
 @Html.EditorFor(m => m.Name)
 @Html.EditorFor(m => m.Address1)
 @Html.EditorFor(m => m.Address2)
 @Html.EditorFor(m => m.Phone1)
<input type="button" value="Register" id="btn1" />
}
<script>
var form = $("#register");
 $("#btn1").click(function (e) {
        e.preventDefault();
        $.ajax({
            url: 'http://localhost:3885/Account/Register',
            data: form.serialize(),
            type: 'POST',
            success: function (result) {},
            error: function (req, status, error) {
                function(req, status, error);
            }
        });
    });
</script>

My Account Model class is as follow :

public class Account
{
   public Name name {get; set;}
   public Address Address1 {get; set;}
   public Address Address2 {get; set;}
   public Phone Phone1 {get;set;}
}

where each Property is also a model class with its own EditorTemplates for example

public class Name
{
   [Required]
   public string FirstName {get; set;} 
   public string MiddleName {get; set;}
   [Required]
   public string LastName {get; set;}
}

and have Name.cshtml EditorTemplate as below

<div >
 @Html.TextBoxFor(m=>m.FirstName);
 @Html.TextBoxFor(m=>m.MiddleName);
 @Html.TextBoxFor(m=>m.LastName);
<div>

similarly for Address.cshtml and Phone.cshtml

in web.config: -

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

On clicking Register button on empty form it does ajax post to Register [HttpPost] Controller method. Why does it not give me client side validation messages i think its called Unobtrusive validation ? I don't see any errors in console as well.

Logarithmic answered 21/5, 2013 at 19:35 Comment(0)
C
28

The submit button must be of type 'submit' to trigger the jquery validate validation, whether using the jquery plugin on its own or with the unobtrusive plugin.

So this would trigger the validation:

<input type="submit" value="Register" id="btn1" />

But seeing as you have already have written some code to handle the button click, it might be easier to just manually trigger the validation

$("#btn1").click(function (e) {

      e.preventDefault();

      // now trigger the form validation, result is 1 or 0
      var result = $('form').valid();  

      $.ajax(
         // details omitted
      );
});
Cyprinodont answered 21/5, 2013 at 20:21 Comment(4)
it worked.Was just wondering why we need to explicitly call form.valid(). Shouldn't it be working without explicit call ??Atleast thats what i have been reading in all the basic examples of unobtrusive validation.Logarithmic
@user check the examples you are following, the forms have submit buttons probably. The plugin performs the validation in response to the form's submit eventCyprinodont
i did use submit button.it doesn't work.it still does ajax postback. is it something to do with ajax post ?Logarithmic
You are using the button click event. If you would use the form submit event than you wouldn't need to call form.valid() yourself because the submit event doesn't trigger when the form is not valid. So instead of $("#btn1").click( use form.submit( and make that button type="submit".Carreno
H
4

I think you need to reorder the scripts references

<script src="~/Scripts/Jquery/jquery-1.9.1.js"></script>
    <script src="~/Scripts/Jquery/jquery-ui-1.10.2.js"></script>
    <script src="~/Scripts/Jquery/jquery.validate.js"></script>
    <script src="~/Scripts/Jquery/jquery.validate.unobtrusive.js"></script>
    <script src="~/Scripts/Jquery/jquery.unobtrusive-ajax.js"></script>
Hagy answered 21/5, 2013 at 19:45 Comment(2)
+1 What did the trick for me was moving jQuery validation bundle above bootstrap js in my view.Interpleader
Holy crap. Moving validation scripts before bootstrap totally did it for us.Raddle
F
1

if your are using the _Layout.cshtml remove the follow reference

@Scripts.Render("~/bundles/jquery")

on the bottom

that work for me!

Fatwitted answered 3/4, 2014 at 3:40 Comment(2)
this doesn't make sense at all, you need to add jquery scripts.Ballonet
I think jkarlos possible meant he was reference jQuery twice.Dilks
H
0

You need also to add the error messages

@Html.EditorFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)

 @Html.EditorFor(m => m.Address1)
@Html.ValidationMessageFor(m => m.Address1)

 @Html.EditorFor(m => m.Address2)
@Html.ValidationMessageFor(m => m.Address2)

 @Html.EditorFor(m => m.Phone1)
@Html.ValidationMessageFor(m => m.Phone1)
Hagy answered 21/5, 2013 at 20:6 Comment(2)
I don't think so as i don't want to show error messages for each field rather I have '@Html.ValidationSummary added at top of main Account view to display summary.Logarithmic
try this @Html.EditorFor(m => m.Name.FirstName)Hagy
M
0

I also had similar problem that required a few weeks to debug. I was using aspx page.

The root cause was that Html.BeginForm statement was placed after a <table> tag.

<table>
   <% using (Html.BeginForm("ContainerManagement", "Admin", FormMethod.Post)){%>
</table>

This caused the <form> tag to close before any <input> tag, and thus the unobtrusive client validation not working.

<form action="/Admin/ContainerManagement" method="post" novalidate="novalidate"></form> <tr> <td><input></td> </tr>

So, remember to put Html.BeginForm before <table> tag

<% using (Html.BeginForm("ContainerManagement", "Admin", FormMethod.Post)){%>
<table>...</table>
<% } %>
Much answered 9/2, 2015 at 10:3 Comment(0)
M
0

I had the same problem and found that if I call 'element.valid()' before library's call to validate function happend, than it will no longer validate my form. I solved this by creating an extension that verifies if the form has been processed and only than verify if the element is valid

 $.fn.revalidate = function () {
        if (this.length) {
            var validator = this.closest("form").data("validator");
            if (validator)
                validator.element(this);
        }
        return this;
    };
Moussorgsky answered 29/10, 2015 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.