I'm trying to implement the code as mentioned in this post. In other words I'm trying to implement unobtrusive validation on a terms and conditions checkbox. If the user hasn't selected the checkbox, then the input should be marked as invalid.
This is the server side Validator code, I've added:
/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value != null && value is bool && (bool)value;
}
}
This is the model
[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
This is my view:
@Html.EditorFor(x => x.AcceptTermsAndConditions)
@Html.LabelFor(x => x.AcceptTermsAndConditions)
@Html.ValidationMessageFor(x => x.AcceptTermsAndConditions)
and this is the jQuery I've used to attach the validator client side:
$.validator.unobtrusive.adapters.addBool("mustbetrue", "required");
The client side script doesn't appear to be kicking in, however. Whenever I press the submit button, validation on the other fields kicks in fine, but the validation for the Terms & conditions doesn't seem to kick in. This is how the code looks in Firebug after I've clicked the submit button.
<input type="checkbox" value="true" name="AcceptTermsAndConditions" id="AcceptTermsAndConditions" data-val-required="The I confirm that I am authorised to join this website and I accept the terms and conditions field is required." data-val="true" class="check-box">
<input type="hidden" value="false" name="AcceptTermsAndConditions">
<label for="AcceptTermsAndConditions">I confirm that I am authorised to join this website and I accept the terms and conditions</label>
<span data-valmsg-replace="true" data-valmsg-for="AcceptTermsAndConditions" class="field-validation-valid"></span>
Any ideas? Have I missed out a step? This is driving me potty!
Thanks in advance S
Sniffer,
In addition to implementing Darin's solution, you also need to modify the file
jquery.validate.unobtrusive.js
. In this file, you must add a "mustbetrue" validation method, as follows:Then (I forgot to add this at first), you must also add the following to
jquery.validate.unobtrusive.js
:counsellorben
I'm unsure why this didn't work for me, but I opted to use your code and do something slightly different.
On my JavaScript load I add the following, this makes the checkbox fire the unabtrusive validation if, either you select the checkbox and uncheck it. Also, if you submit the form.
You also need to add the CSS class to your checkbox, like so.
So, we now need to hook up the model and put in out class to handle the server side validation (which i'm re-using from above) but changing the unobtrusiveness slightly.
Here's the customer attribute that extends IClientValidate as in the above example...
In your model, object property set the desired attribute notations
Okay, we're ready to put in the JavaScript.
What makes this work, is... well. After looking at the HTML markup after trying to do the suggested answer above, my values were all set to true, however my checkbox checked was false. So, I decided to let jQuery work it out using IsChecked
You need to implement IClientValidatable on your custom attribute in order to tie the
mustbetrue
adapter name that you are registering on the client side with this attribute:UPDATE:
Full working example.
Model:
Controller:
View:
For those that none of these solutions are working:
I'm working with Razor MVC 4 using .Net Framework 4, and the latest jquery validate script files.
After implementing the custom attribute validation in client and server side, it still doesn't work. My form is being post anyway.
So here is the catch: JQuery validate script has a default setting of ignore hidden tags where hidden is http://api.jquery.com/hidden-selector/, that won't be a problem normally but the @Html.CheckBoxFor style that I'm using is customized with a CSS3 style that changes the display to none and a custom image of the checkbox is displayed, so it will never execute the validation rule on the checkbox.
My workaround was adding this line before the custom client validation rule declaration:
what it does is override the ignore setting for all validations in the current page, notice that now it could execute validations on hidden field too (a side effect).