Client Side MVC Validation not firing on mouse(Tab) out - asp.net-mvc

Am trying to have client side validation using Data Annotations and JQUERY for my web page.
I have set up my property in model
[Required]
public string Name { get; set; }
And i set up Scripts using Bundle.config which is rendered in my page as below
<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
and in my web.config
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
My HTML is renderd as expected
<input type="text" value="" name="Name" id="Name" data-val-required="The Name field is required." data-val="true" class="text-box single-line">
On click of Submit the Client side validation is firing as Expected.
My problem is Why it is not firing on mouse or Tab out ??
Am i missing something or doing wrong ?? I searched and tried everything but still validation not works on mouse or Tab out.
Even i tried creating a new sample with just one property but still i cant make it work. Any Help would be appreciated
Thanks
---Updated with view code sample ---
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
....
sample code may be brackets missing

Related

Html.ValidationMessageFor not displaying at all

I have the following form:
<form action="~/buy-online" method="get" class="buy-online-form clearfix" autocomplete="off" id="buy-online-search">
<div class="infield-holder clearfix">
#Html.LabelFor(m => m.CustomerPostcode, new { #class = "infield" })
#Html.TextBoxFor(m => m.CustomerPostcode, new { #class = "textbox" })
<input type="submit" value="Buy Online" id="find-retailer-button" class="button" />
</div>
</form>
#Html.ValidationMessageFor(m => m.CustomerPostcode)
Which works fine and will display an error message when submitted without jQuery, but when I add the jQuery validate scripts (v 1.11.1):
<script src="/scripts/jquery.validate.js"></script>
<script src="/scripts/jquery.validate.unobtrusive.js"></script>
It stops the form submitting but doesn't display the error message
My property is marked like so:
[DisplayName("Enter your full postcode")]
[Required(ErrorMessage = "Please enter your full postcode")]
public string CustomerPostcode { get; set; }
And the html renders like this:
<input class="textbox" data-val="true" data-val-required="Please enter your full postcode" id="CustomerPostcode" name="CustomerPostcode" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="CustomerPostcode" data-valmsg-replace="true"></span>
If I inspect the input when I hit submit it is adding the class input-validation-error to the textbox but just not updating the validation message.
All the posts that I have checked on this problem just say to include the scripts so I'm at a loss as to why the message is not showing.
I've even tried adding the jquery.unobtrusive-ajax.js script but that didn't seem to do anything either. Any help would be appreciated, thanks.
You need to include the #Html.ValidationMessageFor(m => m.CustomerPostcode) within the form tags for jquery.validate.unobtrusive to work.

MVC5 Validation Errors in Razor View

I am using MVC5 and having problem displaying the validation errors of an object both in the Validation Summary section and the individual validation messages for each control.
Lets put aside client validation for the moment although we have ENABLED IT in the web config and included the js files.
If a model that is invalid is passed to a view that has in place a Validation Summary (setting excludePropertyErrors to false) and for each control there is a #Html.ValidationMessageFor(model => model.Summary, "", new { #class = "text-danger" }), shoudn't all these display the Validation errors in the object when the page loads.
We checked the object and the framwork knows it is invlaid (ModelState.IsValid is definitely false) and the errors collection contains several validation errors
(System.Data.Entity.Validation.DbValidationError) but none of them show up neither in the ValidationSummary or the ValidationMessage for the individual controls when the page loads.
Currently I am getting he validation errors manually by context.Entry(prop).GetValidationResult().ValidationErrors.ToList(); and passing it to the Viewbag and iterate over them in the view to display them. Seems crazy!
P.S. The main View is composed of several partial views in which the controls are and the Vaidationsummary is in the Main containing view.
public async Task<ActionResult> GetProduct(id)
{
var product= await context.Products.FindAsync(id);
return View(product);
}
As I mentioned , there are NO VALIDATION MESSAGES ANYWHERE. If we turn off client side validation the input control html is
<input class="form-control text-box single-line valid" id="Price" name="Price" style="font-weight:bold" type="text" value="" aria-invalid="false">
As you can see the value is empty BUT it says it is valid even though the field is a required field marked so via DataAnnotations and the Model is INVALID and includes validation error that Price field is required!
Here is the code:
<div class="form-group">
#Html.LabelFor(m => m.Price, new { #class = "col-sm-3 control-label" })
<div class="col-sm-5">
#Html.EditorFor(model => model.Price, new { htmlAttributes = new { #class = "form-control", style = "font-weight:bold" } })
#Html.ValidationMessageFor(model => model.Price, "", new { #class = "text-danger" })
</div>
</div>
And this is the generated html with client side validation enabled :
<input class="form-control text-box single-line" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" style="font-weight:bold" type="text" value="">
Would greatly appreciate any assistance.

ASP.NET MVC, Cancel triggering Client Validation, Why?

I am using MVC3, C#, Razor, .NET 4.5
I have a required field value.
#Html.ValidationMessageFor(model => model.Name)
rendered as :
<input data-val="true" data-val-required="* Required" id="Name" name="Name" style="width:440px" type="text" value="" />
Unfortunately it being triggered by the Cancel button, although buttons defined as:
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
#Html.TextBoxFor(model => model.Name, new {#style="width:440px" })
#Html.ValidationMessageFor(model => model.Name)
<p class="form-buttons">
<button type="submit" name="btn" value="Save">Save</button>
<button type="submit" name="btn" value="Cancel">Cancel</button>
</p>
}
Also it seems to be triggered pre Post Action, so must be via Javascript.
I do not mind JS triggering the validation, but I do need to ensure that the Cancel button just closes the page and returns to another page as handled by the post action if btn != Save.
So how do I stop this Cancel validation please?

In this ASP.NET MVC 3 app, what am I missing to get unobtrusive client-side validation?

I need help figuring out how to succeed in implementing unobtrusive client-side validation of a field in my ASP.NET MVC 3 app. I can see that unobtrusive client-side validation is basically enabled, since MVC generates related HTML.
What I want to achieve in this case is to have validation of input to the Bugs editor (i.e., the corresponding <input> element) as I type, for testing purposes I've set the property's max length to 2. When I test, I can tell that validation does not currently take place, so something is at least missing. So, the success criteria for this question is working client-side validation of the Bugs form field.
I can see one possible problem in the generated HTML: The Verbose property is not marked as Required in the model, but its corresponding <input> still gets the dataval=true attribute for instance, whereas the <input> for Bugs does not. Shouldn't it be the other way around, as fields with validation rules should get dataval=true, to enable unobtrusive validation?
The code that should be relevant to understanding the case follows, please let me know if more info is required:
Options.cs:
public class Options
{
[Required, StringLength(2)]
public string Bugs;
public bool Verbose;
}
Options.cshtml:
<script src="#Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div id="options-form">
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Options</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bugs)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Bugs)
#Html.ValidationMessageFor(model => model.Bugs)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Verbose)
</div>
<div class="editor-field">
#Html.CheckBoxFor(model => model.Verbose)
#Html.ValidationMessageFor(model => model.Verbose)
</div>
</fieldset>
}
</div>
The two editors (for Bugs and Verbose) are rendered as follows:
<div id="options-form">
<form action="/Options" method="post">
<fieldset>
<legend>Options</legend>
<div class="editor-label">
<label for="Bugs">Bugs</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Bugs" name="Bugs" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Bugs" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="Verbose">Verbose</label>
</div>
<div class="editor-field">
<input data-val="true" data-val-required="The Boolean field is required." id="Verbose" name="Verbose" type="checkbox" value="true" /><input name="Verbose" type="hidden" value="false" />
<span class="field-validation-valid" data-valmsg-for="Verbose" data-valmsg-replace="true"></span>
</div>
</fieldset>
</form>
</div>
Bugs and Verbose are public fields in this code, not properties. Make them properties and that should fix it.
Define get; and set; for both Bugs and Verbose properties. That will not just correct(add) validation, but in the future, model binder will be able to bind models back from form fields on server.
And regarding required attribute for Verbose. That is because of implicit required validation for value types taking place. string is nullable, so it is not required if you do not set Required attribute on it explicitely - so Bugs stays without required. But bool cannot be null by nature of c#, so mvc automatically adds Required attribute to it. You can control that with
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
I experienced the same problem recently (unobtrusive client-side validation didn't work in IE but worked in the other browsers though). The reason was in jQuery version. I rolled back from jQuery 1.6.x version to the version 1.5.2 an it started to work.

Why doesn't ASP.NET MVC 3 enable client-side validation in this case?

I'm trying to integrate unobtrusive client-side validation in my ASP.NET MVC 3 project, as per Brad Wilson's recipe. However, it does not get enabled in the rendered view. For example, my <input> elements (i.e., editor fields) do not receive a data-val attribute as prescribed.
I have done the following to enable unobtrusive client-side validation:
Web.config:
<configuration>
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
</configuration>
Options.cs:
public class Options
{
// Annotate with validation rules, in order to generate client-side validation code
[Required, StringLength(60)]
public string Bugs = "";
}
_Layout.cshtml:
<head>
<script src="#Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
</head>
Options.cshtml:
#model MyProject.Models.Options
<div id="options-form">
#Html.ValidationSummary(true)
<fieldset>
<legend>Options</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bugs)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Bugs)
#Html.ValidationMessageFor(model => model.Bugs)
</div>
</fieldset>
</div>
This HTML gets generated for the editor field:
<div class="editor-label">
<label for="Bugs">Bugs</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Bugs" name="Bugs" type="text" value="" />
As you can see, no data-val attribute :(
You forgot to use form. Surround your fieldset with Html.BeginForm
<div id="options-form">
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Options</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Bugs)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Bugs)
#Html.ValidationMessageFor(model => model.Bugs)
</div>
</fieldset>
}
</div>
This will initialize FormContext and your inputs will receive data-val-* validation attributes

Resources