It was difficult for me to get an unobtrusive check to work when submitting a form via an ajax request in my MVC 4 project. For reference, the person in this thread does almost the same thing as I do:
Manual form validation in MVC 3 and jQuery
I went through what was done there, but I still can't get it to work. The problem is that when I do $ ("# Form"). Valid (), it always returns true, even if I send a request, the model is invalid. I have the appropriate scripts installed in my packages, but I canโt get the form for validation on the client side. How can I check this correctly? I thought that after creating data annotations it should โworkโ, but this is clearly not the case.
In addition, this particular form is loaded using jQuery in a Kendo user interface window with a partial view. Seeing the answer to this post: Asp MVC unobtrusive Client Validation always returns true using the form identifier as a selector, and .valid () still returns true, but the class name is false. However, the guid identifier returns true.
My code is below:
Model
public class Class { public Class() { ClassId = Guid.NewGuid(); } [Key] public Guid ClassId { get; set; } [Display(Name = "Class Name")] [Required(ErrorMessage = "A Class Name is required.")] public string ClassName { get; set; } public int UserId { get; set; } [Display(Name = "Term Type")] [Required(ErrorMessage = "The Term Type is required.")] public Guid SemesterId { get; set; } [ForeignKey("SemesterId")] public virtual Semester Semester { get; set; } [Display(Name = "Class Year")] public int Year { get; set; } [Display(Name = "Has Weighted Grades?")] public bool HasWeightedGrades { get; set; } public virtual List<Grade> Grades { get; set; }
}
The form
@using (Html.BeginForm("AddClass", "", FormMethod.Post, new { name = "AddNewClassForm", id = "AddNewClassForm" })) { <div> <div>@Html.LabelFor(m => m.ClassName)</div> <div> @Html.TextBoxFor(m => m.ClassName, new { @class = "input-xlarge" }) @Html.ValidationMessageFor(m => m.ClassName) </div> <div>@Html.LabelFor(m => m.SemesterId)</div> <div> @Html.DropDownList("SemesterId", null, "-- Select a Term Type --", new { @class = "input-xlarge" }) @Html.ValidationMessageFor(m => m.SemesterId) </div> </div> } <div> <button id="AddClassButton" class="btn btn-primary" type="submit"><i class="icon-plus icon-white"></i> Add Class</button> <button id="CancelAddClassButton" class="btn btn-danger" type="submit"><i class="icon-ban-circle icon-white"></i> Cancel</button> </div>
JQuery event
//================================================================================================================================ // AddClassButton: Click event handlers. //================================================================================================================================ $('#AddClassButton').unbind('click').bind('click', function (e) { $.validator.unobtrusive.parse($('#AddClassWindow')); var val = $("#AddNewClassForm").validate(); val.showErrors(); alert("Is the form valid? " + val.valid()); //Always returns true alert("Is Class Name Valid? " + $("#ClassName").valid()); //Still returns true alert("Is Semester Id Valid? " + $("#SemesterId").valid()); //Still returns true e.preventDefault(); // Prevent this from doing default (possibly submit form). e.stopPropagation(); // Prevent infinite loop. });
Bunches
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.unobtrusive*", "~/Scripts/jquery.validate*"));
Controller action
[Authorize] public ActionResult AddClass() { var userName = User.Identity.Name; var userProfile = db.UserProfiles.SingleOrDefault(x => x.UserName == userName); InitializeSemesters(); InitializeYears(); return PartialView(new Class() { UserId = userProfile.UserId, Year = DateTime.Now.Year }); }