I want my \"Agree To Terms\" checkbox to be mandatory using jQuery validate, in an MVC3 project. I currently get server/client DRY/SPOT validation from \"MS data annotation
<asp:Content ID="Content1" ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
<h2>
Save New Contact</h2>
<%using (Html.BeginForm("SaveContact", "Contact", FormMethod.Post, new { id = "UserImportTypeForm", @autocomplete = "off" })) %>
<%{ %>
<table style="height: 100px;">
<tr>
<td>
Import Type :
</td>
</tr>
<tr>
<td>
Is Verified
</td>
<td>
<%-- <%=Html.TextBox("UserContactModel.IsVerified", new SelectList(Model.IsVerified, "IsVerified"), new { })%>>--%>
<%-- <input type="text" name="txtIsVerified" id="txtIsVerified" />--%>
<%-- <%= Html.TextBox("txtIsVerified")%>--%>
<%=Html.CheckBox("SelectedUserContact.IsVerified", Convert.ToBoolean(Model.SelectedUserContact.IsVerified) )%>
<%=Html.ValidationSummary("txtIsVerified", "*")%>
</td>
</tr>
<tr>
<td>
First Name
</td>
<td>
<%--<input type="text" name="txtFirstName" id="txtFirstName" />--%>
<%=Html.TextBox ("SelectedUserContact.FirstName", Model.SelectedUserContact.FirstName )%>
<%-- <%=Html.ValidationSummary("FirstName", "*")%>--%>
</td>
</tr>
<tr>
<td>
Last Name
</td>
<td>
<%--<input type="text" name="txtLastName" id="txtLastName" />--%>
<%=Html.TextBox("SelectedUserContact.LastName", Model.SelectedUserContact.LastName)%>
<%=Html.ValidationSummary("LastName", "*")%>
</td>
</tr>
<tr>
<td>
Contact ID
</td>
<td>
<%=Html.TextBox("SelectedUserContact.ContactID",Model.SelectedUserContact.ContactID) %>
<%=Html.ValidationSummary("ContactID","*") %>
</td>
</tr>
<tr>
<td align="right">
<input type="submit" value="Save" name="btnSave" id="btnSave" />
</td>
<td>
<input type="button" value="Cancel" name="btnCancel" id="btnCancel" />
</td>
</tr>
</table>
<%} %>
<script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$("#UserImportTypeForm").validate({
rules:
{
"SelectedUserContact.FirstName": { required: true },
"SelectedUserContact.LastName": { required: true },
"SelectedUserContact.ContactID": {required:true}
},
messages:
{
"SelectedUserContact.FirstName": { required: "*" },
"SelectedUserContact.LastName": { required: "*" },
"SelectedUserContact.ContactID": { required: "*" },
}
});
</script>
</asp:Content>
I've summarized here the correctly-working source code, which resulted from applying the accepted answer. Hope you find it useful.
RequiredCheckbox.aspx
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<RegistrationViewModel>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>RequiredCheckbox</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
<script src="//ajax.microsoft.com/ajax/jQuery.Validate/1.7/jQuery.Validate.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
$.validator.unobtrusive.adapters.addBool("mandatory", "required");
</script>
</head>
<body>
<div>
<%
// These directives can occur in web.config instead
Html.EnableUnobtrusiveJavaScript();
Html.EnableClientValidation();
using (Html.BeginForm())
{ %>
<%: Html.CheckBoxFor(model => model.IsTermsAccepted)%>
<%: Html.ValidationMessageFor(model => model.IsTermsAccepted)%>
<%: Html.TextBoxFor(model => model.ContactName)%>
<%: Html.ValidationMessageFor(model => model.ContactName)%>
<button type="submit">Submit</button>
<% } %>
</div>
</body>
</html>
RegistrationViewModel.cs
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class RegistrationViewModel {
[Mandatory (ErrorMessage="You must agree to the Terms to register.")]
[DisplayName("Terms Accepted")]
public bool isTermsAccepted { get; set; }
[Required]
[DisplayName("Contact Name")]
public string contactName { get; set; }
}
MandatoryAttribute.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public class MandatoryAttribute : ValidationAttribute, IClientValidatable
{
public override bool IsValid(object value)
{
return (!(value is bool) || (bool)value);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "mandatory";
yield return rule;
}
}
Just change your javascript to this:
(function ($) {
// http://itmeze.com/2010/12/checkbox-has-to-be-checked-with-unobtrusive-jquery-validation-and-asp-net-mvc-3/
$.validator.unobtrusive.adapters.add("mandatory", function (options) {
options.rules["required"] = true;
if (options.message) {
options.messages["required"] = options.message;
}
});
} (jQuery));
You do not actually need to write your own adapter though and can just use:
(function ($) {
$.validator.unobtrusive.adapters.addBool("mandatory", "required");
} (jQuery));