Question

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.

Was it helpful?

Solution

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
      );
});

OTHER TIPS

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>

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

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

on the bottom

that work for me!

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)

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>
<% } %>

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;
    };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top