The issue appears to be that the Unobtrusive library interprets "required" differently than jQuery Validation when it comes to checkboxes. Unobtrusive interprets "required" as having a value and in the typical use case (as part of .NET MVC) a checkbox will always have a value.
Though the source is old, the following information is still relevant:
Yes Validation is not performed for checkboxes because the programmers that wrote the adapter says that required is different [from] mandatory...A required validation attribute must trigger if no value is provided! An unchecked checkbox has a a value: the false value!
See here the source code of the adapter for the required attribute:
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
I did find a way to get Unobtrusive to behave in the desired manner, and that was to set up validation so that the value of the field must equal itself (using the "equalto" validation):
.field-validation-error {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.validate.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.validate.unobtrusive.min.js"></script>
<form>
<p>
<label>
<input id="AcceptLaws" type="checkbox" name="AcceptLaws" data-val="true" data-val-equalto="You must accept the cited laws" data-val-equalto-other="AcceptLaws" />
I accept
</label>
<br>
<span class="field-validation-valid" data-valmsg-for="AcceptLaws" data-valmsg-replace="true"></span>
</p>
<p>
<button type="button" onclick="$('#AcceptLaws').valid();">Accept</button>
</p>
</form>