I have created a custom validation attribute which works server-side (after form is posted) but I cannot get the validation to work client-side.
The custom attribute is:
public class ReasonableAttribute : ValidationAttribute, IClientValidatable
{
public override bool IsValid(object value)
{
return Approval.IsNumberReasonable(value.ToString());
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "reasonable";
yield return rule;
}
}
The IsNumberReasonable()
function just does some checks on the fields input to make sure what they entered could reasonably be an Approval number (e.g. not empty, or "Unknown" or something like that) returning a bool true/false
.
My Model then contains:
[Display(Name = "Approval Number"]
[Reasonable(ErrorMessage = "Please enter a reasonable {0}")]
public String ApprovalNumber { get; set; }
and the View contains:
@Html.LabelFor(model => model.ApprovalNumber, new { @class = "control-label col-md-3" })
<div class="col-md-9 append field">
@Html.TextBoxFor(model => model.ApprovalNumber, new { @class = "input text" })
@Html.ValidationMessageFor(model => model.ApprovalNumber)
</div>
in the JavaScript I have tried adding:
$.validator.unobtrusive.adapters.addBool("reasonable", "required");
// OR
$.validator.unobtrusive.adapters.add("reasonable");
and: (outside of document.ready)
(function ($) {
$.validator.addMethod('reasonable', function (value, element, params) {
return value != '';
}, 'Clientside Should Not Postback');
$.validator.unobtrusive.adapters.addBool('reasonable');
})(jQuery);
in various combinations but have not been able to get it to work.
I have got
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
included in the View.
When the form is submitted, client-side validation works for other fields (required ones etc) but the validation message next to the ApprovalNumber never appears/does not perform my custom validation.
Any pointers in the right direction are appreciated. thanks.
I also have
<configuration>
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
</configuration>
Already in the Web.config file.
Edit 2: as per chenZ's post: The html for the input field is:
<input class="input text valid" data-val="true" data-val-reasonable="Please enter a reasonable Approval Number" data-val-required="Approval Number is Required." id="ApprovalNumber" name="ApprovalNumber" type="text" value="">
Tried updating the bottom of my view with:
<script src="~/Scripts/jquery.validate.js"></script>
<script type="text/javascript">
(function ($) {
$.validator.addMethod('reasonable', function (value, element, params) {
return value != '';
}, 'Clientside Should Not Postback');
})(jQuery);
</script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/Create.js"></script>
where the end of jquery.validate.unobtrusive.js
now contains:
$(function () {
$.validator.unobtrusive.adapters.addBool('reasonable');
$("#formID").removeData("unobtrusiveValidation").removeData("validator");
$jQval.unobtrusive.parse(document);
});
}(jQuery));
and create.js
contains:
$.validator.unobtrusive.adapters.addBool("mandatory", "required"); // another custom attribute for checkbox validation
var v = $("#formID").validate({
errorClass: "warning",
onkeyup: false,
onblur: false,
});
the v
variable is used further down for the submit button:
$("#SubmitButton").click(function () {
if (v.form()) {
// The form passed validation so continue..
} else {
// Validation failed, do something else..
}
});
I did some further testing ans it appears to be something to do with the:
(function ($) {
$.validator.addMethod('reasonable', function (value, element, params) {
return value != '';
}, 'Clientside Should Not Postback');
})(jQuery);
when I change it to:
(function ($) {
$.validator.addMethod('reasonable', function (value, element, params) {
return value != 'unknown';
}, 'Clientside Should Not Postback');
})(jQuery);
it works, but only if I type 'unknown' into the input box, anything else passes.. similarly if I put return value != 'jhdsfkhsdkfj';
it only validates when I input jhdsfkhsdkfj.
so it appears that it is using that as the rule? instead of my server-side IsNumberReasonable()
function.
hope that helps in troubleshooting.