Using jQuery unobtrusive validation within a .NET MVC project and that seems to be working fine. I'm now trying to show a green checkmark when the field validates correctly (client-side and/or remote).
Here's a sample field declaration:
<div class="clearfix">
@Html.LabelFor(model => model.Address1, "Street")
<div class="input">
@Html.TextBoxFor(model => model.Address1, new { @class = "xlarge", @maxlength = "100", @placeholder = "e.g. 123 Main St" })
<span class="help-message">
@Html.ValidationMessageFor(model => model.Address1)
<span class="isaok">Looks great.</span>
</span>
<span class="help-block">Enter the street.</span>
</div>
</div>
What I'd like to do is add a class 'active' to the "span.isaok" which in turn has a checkmark for a background image.
I tried using highlight/unhighlight:
$.validator.setDefaults({
onkeyup: false,
highlight: function (element, errorClass, validClass) {
$(element).addClass(errorClass).removeClass(validClass);
$(element.form).find("label[for=" + element.id + "]").addClass("error");
$(element).parent().find("span.isaok").removeClass("active");
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass(errorClass).addClass(validClass);
$(element.form).find("label[for=" + element.id + "]").removeClass("error");
if ($(element).val().length > 0) {
$(element).parent().find("span.isaok").addClass("active");
}
}
});
but that shows a green checkmark for all fields even if they're empty! (hence obviously wrong)
I then tried using the 'success' option but that never seems to be fired.
What am I missing?
Edit: So I found this blog post and was able to tap into the success function i.e.
$(function () {
var settings = $.data($('form')[0], 'validator').settings;
settings.onkeyup = false;
settings.onfocusout = function (element) { $(element).valid(); };
var oldErrorFunction = settings.errorPlacement;
var oldSuccessFunction = settings.success;
settings.errorPlacement = function (error, inputElement) {
inputElement.parent().find("span.isaok").removeClass("active");
oldErrorFunction(error, inputElement);
};
settings.success = function (label) {
var elementId = '#' + label.attr("for");
$(elementId).parent().find("span.isaok").addClass("active");
oldSuccessFunction(label);
};
});
but now if the form isn't valid it shows both the error message and the valid mark...
and the latter disappears as soon as I click anywhere on the page.
This is not a direct answer to your question. I am going to offer an alternative approach to this: TwitterBootstrapMVC.
With this library all you'd have to write for each input is:
And that's it. You will have label, input, and validation message - all taken care of, without javascript. It generates proper html mark up for you. You just need to make sure that you have proper standard css for classes like
.field-validation-error
,.field-validation-valid
...In case any one has a similar problem, I finally got this working by using the un-minified version of jquery.validate.unobtrusive.js and adding my js to the onError and onSuccess methods. Existing code was left as it. Use the re-minified version during deployment.
Thanks.
This appears to be an issue with the jquery.validate.unobtrusive interfering with the settings added later in
$.validator.setDefault
. The trick is to load the unobtrusive script after the custom settings. See here and vote to fix it here.