Html.ValidationMessageFor not displaying at all - asp.net-mvc

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.

Related

DropDown part of the EnumDropDownListFor not styled for bootstrap

I'm using the new (for ASP.NET MVC 5.1) EnumDropDownListFor function, in a bootstrap-styled page.
The bootstrap style is correctly applied to the control, but when I open the dropdown part, it is not styled at all, for what I can see.
My call is:
#using (Html.BeginForm(..., new { role = "form" }))
{
...
<div class="form-group">
#(Html.Label("AAA))
#(Html.EnumDropDownListFor(m => m.MyField, new { #class = "form-control" }))
</div>
<input type="submit" value="Go" class="k-button" />
}
and I'm loading the appropriate CSS styles:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
What am I missing?
UPDATE
Upon request, this is the output of the dropdown:
<select class="form-control" data-val="true" data-val-required="The OP field is required." id="OP" name="OP">
<option selected="selected" value="0">Text1</option>
<option value="1">Text2</option>
</select>

Client Side MVC Validation not firing on mouse(Tab) out

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

Why am I getting this Javascript HIERARCHY_REQUEST_ERR with jQuery Mobile and Razor?

Dazed and confused here... The field in question is a boolean, and I want the UI to be a checkbox (or a yes/no or on/off jQuery slider). Each time I try to add in this checkbox input, I end up getting a
Microsoft JScript runtime error: DOM Exception: HIERARCHY_REQUEST_ERR (3)
error.
Here's the HTML+Razor
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
#Html.TextBoxFor(model => model.HandicapSession.WinByTwo, new { #type="checkbox" })
<label for="WinByTwo">Win By Two?</label>
</fieldset>
</div>
Here's the generated HTML:
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input data-val="true" data-val-required="The WinByTwo field is required." id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" type="checkbox" value="False" />
<label for="WinByTwo">Win By Two?</label>
</fieldset>
</div>
Apparently this error occurs when there are conflicting or overlapping id's as jQuery Mobile creates its checkbox widget
$.widget( "mobile.checkboxradio", $.mobile.widget, { ...etc...
But how do I use the HTML and/or razor to make a simple checkbox work in jQuery Mobile?
If the problem with jQuery Mobile really is duplicate names for the HTML tags, then you'll have to render your own input type=checkbox tag in HTML, as the ASP.NET MVC Html.CheckBoxFor helper method will render an input type=hidden tag with a duplicate name value. See this post for a discussion.
The hidden form tag is there because if you submit an unchecked checkbox to the server, the form value for that field isn't included. So a hidden input tag is included with value=false so that if the checkbox is unchecked, the value false is still submitted. The model binding process in MVC will filter out the duplicate form values for you, but if you're having a client-side problem with the duplicate name attributes, you'll have to render your own checkbox and label in HTML, then handle the fact that no value will be submitted for the HandicapSession.WinByTwo property when the box is unchecked. If no other property for HandicapSession is submitted, then that whole object will be null.
So, you can manually create the checkbox input and still load the checked and value attributes from your model, as desired, but you can run into model binding problems where the value for WinByTwo will still be false even when the box is checked.
Note also that the for attribute on your label doesn't match the ID of the checkbox in your sample. You need the full HandicapSession_WinByTwo.
The following manually creates the input tags:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
<div data-role="page">
<div data-role="content">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input type="checkbox" id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" #(Model.HandicapSession.WinByTwo ? "checked=checked" : "") value="#(Model.HandicapSession.WinByTwo.ToString().ToLower())" />
<label for="HandicapSession_WinByTwo">Win By Two?</label>
</fieldset>
</div>
</div>
</div>
The HTML output is as follows for a checked checkbox on load:
<div data-role="page">
<div data-role="content">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input type="checkbox" id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" checked=checked value="true" />
<label for="HandicapSession_WinByTwo">Win By Two?</label>
</fieldset>
</div>
</div>
</div>
The best would be just to use the MVC helper methods, so I'm not sure if you'd tried the following. The default Html.CheckBoxFor and Html.LabelFor helper methods work with jQuery Mobile 1.0a4.1 or 1.1.0 just fine. The following works for me:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
<div data-role="page">
<div data-role="content">
#using (Html.BeginForm())
{
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
#Html.CheckBoxFor(m => m.HandicapSession.WinByTwo)
#Html.LabelFor(m => m.HandicapSession.WinByTwo, "Win By Two?")
<input type="submit" id="SubmitForm" value="submit" />
</fieldset>
</div>
}
</div>
</div>
This produces the HTML output:
<div data-role="page">
<div data-role="content">
<form action="/Mobile/Mobile" method="post">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input checked="checked" data-val="true" data-val-required="The WinByTwo field is required." id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" type="checkbox" value="true" />
<input name="HandicapSession.WinByTwo" type="hidden" value="false" />
<label for="HandicapSession_WinByTwo">Win By Two?</label>
<input type="submit" id="SubmitForm" value="submit" />
</fieldset>
</div>
</form>
</div>
</div>
Fix might be pretty simple.
Choice 1: Go scorched earth and turn off Ajax based navigation. This will ensure that unique IDs stay unique. This will ensure that you never encounter this issue again. Only downside is that you lose the pretty little transitions from page to page (someone call the whambulance). You can do this by setting up a global configuration script...
script src="jquery.js"
script src="custom-scripting.js"
script src="jquery-mobile.js"
inside that you'll override the ajax settings to disable them...
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
Choice 2: Call pages that are going to require this uniqueness with a link that has an attribute of rel='external' or target='_black' which will accomplish the same thing without disabling all ajax based navigation. If you are reaching the page as a results of a form post, you can use data-ajax='false' on the form tag to accomplish a clean load.

MVC - Cannot seem to post to controller action using AJAX helper

I'm having issues posting a model to a controller action using the AJAX helper. The controller action doesn't get hit at all.
Code:
View:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ServiceNumberModel>" %>
<div id="ServiceNumberPanel">
<h1>
Based on your location we offer different plans</h1>
<% using (Ajax.BeginForm("AvailablePlans", "ServiceCheck", new AjaxOptions { UpdateTargetId = "AdslPlansPanel", HttpMethod = "Post" } ))
{ %>
<%=Html.ValidationSummary(true)%>
Your Phone Number:
<%=Html.TextBoxFor(m => m.HomePhoneNumber)%><br />
<%=Html.CheckBoxFor(m => m.BundleWithHomePhone)%>Bundle with Home Phone? <br/>
<input id="CheckServiceAvailabilityButton" type="submit" value="Check"/>
<% } %>
</div>
Model:
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace ServiceCheck
{
public class ServiceNumberModel
{
[Required(ErrorMessage = "Please enter your phone number.")]
[RegularExpression(#"^[0]\d{9}$", ErrorMessage = "Please enter your phone number, including the area code")]
[DisplayName("Phone Number:")]
public string HomePhoneNumber { get; set; }
public bool BundleWithHomePhone { get; set; }
}
}
Controller:
[HttpPost]
public ActionResult AvailablePlans(ServiceNumberModel serviceNumberModel)
{
if (serviceNumberModel.BundleWithHomePhone)
return ReturnAvailableBundledPlans(serviceNumberModel);
return View("Index");
}
Generated HTML:
<div id="ServiceNumberPanel">
<h1>
Based on your location we offer different plans</h1>
<form action="/ServiceCheck/AvailablePlans" data-ajax="true" data-ajax-method="Post" data-ajax-mode="replace" data-ajax-update="#AdslPlansPanel" id="form0" method="post">
Your Phone Number:
<input data-val="true" data-val-regex="Please enter your phone number, including the area code" data-val-regex-pattern="^[0]\d{9}$" data-val-required="Please enter your phone number." id="HomePhoneNumber" name="HomePhoneNumber" type="text" value="" /><br />
<input data-val="true" data-val-required="The BundleWithHomePhone field is required." id="BundleWithHomePhone" name="BundleWithHomePhone" type="checkbox" value="true" /><input name="BundleWithHomePhone" type="hidden" value="false" />Bundle with Home Phone? <br/>
<input id="CheckServiceAvailabilityButton" type="submit" value="Check"/>
</form>
</div>
Behaviour:
When I click on submit, I get 'Resource cannot be found error':
The resource cannot be found. Description: HTTP 404. The resource you
are looking for (or one of its dependencies) could have been removed,
had its name changed, or is temporarily unavailable. Please review
the following URL and make sure that it is spelled correctly.
Requested URL: /ServiceCheck
Interestingly when I look at the source using firebug, I cannot see the form tags:
<div class="ExistingContent">
<h1>ServiceCheck</h1>
<div id="ServiceNumberPanel">
<div id="ServiceNumberPanel">
<h1> Based on your location we offer different plans</h1>
Your Phone Number:
<input id="HomePhoneNumber" type="text" value="" name="HomePhoneNumber" data-val-required="Please enter your phone number." data-val-regex-pattern="^[0]\d{9}$" data-val-regex="Please enter your phone number, including the area code" data-val="true">
<br>
<input id="BundleWithHomePhone" type="checkbox" value="true" name="BundleWithHomePhone" data-val-required="The BundleWithHomePhone field is required." data-val="true">
<input type="hidden" value="false" name="BundleWithHomePhone">
Bundle with Home Phone?
<br>
<input id="CheckServiceAvailabilityButton" type="submit" value="Check">
</div>
<div id="Div1">
</div>
</div>
Also, if I change the view to use the HTML helper it hits the controller without issue:
<div id="Div1">
<h1>
Based on your location we offer different plans</h1>
<% using (Html.BeginForm("AvailablePlans", "ServiceCheck"))
{ %>
<%=Html.ValidationSummary(true)%>
Your Phone Number:
<%=Html.TextBoxFor(m => m.HomePhoneNumber)%><br />
<%=Html.CheckBoxFor(m => m.BundleWithHomePhone)%>Bundle with Home Phone? <br/>
<input id="Submit1" type="submit" value="Check"/>
<% } %>
</div>
Please help!!!
I managed to find the issue.
In the master page I was using, which is shared across a number of applications, someone had added a rouge form:
<body>
<form id="form1" runat="server">
<uc1:header id="Header1" runat="server" />
<div class="ExistingContent">
<asp:contentplaceholder id="MainContent" runat="server" />
</div>
<uc2:footer id="Footer1" runat="server" />
</form>
</body>
This meant that I was trying to submit a form from within a form and the framework was defaulting to the parent.
Once removed, everything began to work as expected.

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.

Resources