ASP.NET MVC 4 - Clientside Validation Not Working
I'm wondering what would happen if you altered nevervalid.js so that the code executes before the document is ready.
My basic thinking is that the unobtrusive validation works by parsing the document when the dom is ready... but if you're loading your custom validation stuff at the same time / afterwards, it's not going to know what to do when it comes accross you custom validation data- attribute.
Anyway, try changing nevervalid.js to simply be:
(function($) {
$.validator.addMethod("nevervalid", function () {
return false;
}, "Clientside Should Not Postback");
$.validator.unobtrusive.adapters.addBool("nevervalid");
})(jQuery);
Comments
-
G2Mula almost 2 years
I am using Visual Studio 2012 and I cannot get a custom attribute client side logic to work to reproduce at a smaller scale, I created a new MVC 4 project I created the following model and Attribute that will never validate
public class MyModel { public int Id { get; set; } [Required] public string LastName { get; set; } [NeverValid(ErrorMessage="Serverside Will Never Validate")] public string FirstName { get; set; } } public class NeverValidAttribute : ValidationAttribute, IClientValidatable { public override bool IsValid(object value) { return false; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName }); } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = this.ErrorMessage, ValidationType = "nevervalid" }; } }
I then have the following actions added to the HomeController
public ActionResult Index() { return View(new MyModel()); } [HttpPost] public ActionResult Index(MyModel model) { if (!ModelState.IsValid) { // Will Always Be Invalid } return View(model); }
There is also a javascript file called nevervalid.js
$(function () { $.validator.addMethod("nevervalid", function () { return false; }, "Clientside Should Not Postback"); $.validator.unobtrusive.adapters.addBool("nevervalid"); });
and the Index View
@model CustomAttribute.Models.MyModel @{ ViewBag.Title = "Home Page"; } @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>MyModel</legend> @Html.HiddenFor(model => model.Id) <div class="editor-label"> @Html.LabelFor(model => model.LastName) </div> <div class="editor-field"> @Html.EditorFor(model => model.LastName) @Html.ValidationMessageFor(model => model.LastName) </div> <div class="editor-label"> @Html.LabelFor(model => model.FirstName) </div> <div class="editor-field"> @Html.EditorFor(model => model.FirstName) @Html.ValidationMessageFor(model => model.FirstName) </div> <p> <input type="submit" value="Save" /> </p> </fieldset> } @section Scripts { @Scripts.Render("~/bundles/jqueryval") @Scripts.Render("~/Scripts/nevervalid.js") }
The relevant areas in my web.config look like this
<appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings>
when the page loads, the following files are loaded (got this from network tab under chrome's F12)
http://localhost:7440/ http://localhost:7440/Content/site.css http://localhost:7440/Scripts/modernizr-2.5.3.js http://localhost:7440/Scripts/jquery-1.7.1.js http://localhost:7440/Scripts/jquery.unobtrusive-ajax.js http://localhost:7440/Scripts/jquery.validate.js http://localhost:7440/Scripts/jquery.validate.unobtrusive.js http://localhost:7440/Scripts/nevervalid.js
and my custom attribute adds relevant looking data- stuff to the first name input like so...
<input class="text-box single-line valid" data-val="true" data-val-nevervalid="Serverside Will Never Validate" id="FirstName" name="FirstName" type="text" value="">
so, I ask you, why oh why does this thing have to postback to do serverside validation while I have some perfectly looking javascript code here? do I have to sacrifice some animal on a moonless night on top of a hill somewhere?
-
Patrick Magee about 11 yearsDoes this help, it seems you're not overriding all the required functions in your validation attribute. stackoverflow.com/questions/8284207/…
-
G2Mula about 11 yearsHi, Patrick, thanks for taking your time to look at the problem, In my rush to get the smallest reproducable code, I overlooked the second IsValid override... still it does not work... I think I must've gone through all the related SO questions. but nothing... I'm hoping that someone may be able to reproduce it on their end of the world, confirm I aint going insane...
-
-
G2Mula about 11 yearsyea, still works and the edit does look much more less "naked", been using jQuery for too long and there are some stuff in it I forgot to ask what they actually mean...
-
Charlino about 11 yearsAll good, glad it fixed you problem. The edit was just a best practice thing :-)
-
Seyed Morteza Mousavi over 10 yearsCan anyone help me what is difference between (function($){})(jQuery) and $(document).ready(function{})??
-
G2Mula over 10 years$(document).ready(function{}) gets called when the document is ready (everything has loaded dome is ready blah blah...) (function($){})(jQuery) will be fired immediately it is encountered, it is basically just function($){} called immediately with jQuery as the parameter... hope it makes sense
-
Dilip Langhanoja over 10 yearsThanks a lot @Charlino after many struggle your answer is very useful to me. I wish I can give you more votes for your answer.
-
Box Very over 3 yearsThanks for that, that's very helpful, I didn't pay much attention on that subtle part. However, this subtle part change the whole picture. :-)