Reputation: 11990
I have an ASP.NET MVC 5 base project in which I use css bootstrap for designing my pages.
To work property with css bootstrap. I want to be able to override the default behavior of the errorElement
, errorClass
, highlight
,unhighlight
and errorPlacement
properties/functions.
This is what I have tried
First, I included the packages in the following order
This is my first attempt into overriding the package
$.validator.setDefaults({
errorElement: "span",
errorClass: "help-block",
highlight: function (element, errorClass, validClass) {
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function (element, errorClass, validClass) {
$(element).closest('.form-group').removeClass('has-error');
},
errorPlacement: function (error, element) {
var elm = $(element);
console.log('errorPlacement was called');
if (elm.parent('.input-group').length) {
console.log('parent');
console.log(elm.parent());
error.insertAfter(elm.parent());
}
else if (elm.prop('type') === 'checkbox' || elm.prop('type') === 'radio') {
error.appendTo(elm.closest(':not(input, label, .checkbox, .radio)').first());
} else {
error.insertAfter(elm);
}
}
});
However, the above code will never call the errorPlacement
function, other than that everything else works as expected. But since the errorPlacement
method is not being called, the error is being placed in a different place.
Then I changed the above code to this (overriding both jQuery validation and the Unobtrusive)
$.validator.setDefaults({
errorElement: "span",
errorClass: "help-block",
highlight: function (element, errorClass, validClass) {
console.log('highlight was called');
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function (element, errorClass, validClass) {
console.log('highlight was called');
$(element).closest('.form-group').removeClass('has-error');
},
errorPlacement: function (error, element) { }
});
$.validator.unobtrusive.options = {
errorPlacement: function (error, element) {
var elm = $(element);
console.log('errorPlacement was called');
if (elm.parent('.input-group').length || elm.parent('.input-group-custom').length) {
console.log('parent');
console.log(elm.parent());
error.insertAfter(elm.parent());
}
else if (elm.prop('type') === 'checkbox' || elm.prop('type') === 'radio') {
error.appendTo(elm.closest(':not(input, label, .checkbox, .radio)').first());
} else {
error.insertAfter(elm);
}
}
};
Now, the function errorPlacement
is being called. But, the error is being inserted multiple time. Somehow the code the removes the error message is not being called now.
How can I fix this issue?
Upvotes: 8
Views: 3904
Reputation: 384
This is how I override jQuery Unobtrusive Validation to work with Bootstrap 4.
$.validator.setDefaults({
errorClass: "",
validClass: "",
highlight: function (element, errorClass, validClass) {
$(element).addClass("is-invalid").removeClass("is-valid");
$(element.form).find('[data-valmsg-for="' + element.name + '"]').addClass("invalid-feedback");
},
unhighlight: function (element, errorClass, validClass) {
$(element).addClass("is-valid").removeClass("is-invalid");
$(element.form).find('[data-valmsg-for="' + element.name + '"]').removeClass("invalid-feedback");
},
});
Copy and paste the code above into a new file. Name it jquery.validate.overrides.js
.
Edit BundleConfig.cs. Find the bundle jqueryval
. Add path to new file at the end.
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
"~/Scripts/jquery.validate.overrides.js"
));
To use in a view:
<div class="form-group">
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName, new { @class = "form-control", placeholder = "First name", type = "text" })
@Html.ValidationMessageFor(m => m.FirstName)
</div>
Upvotes: 16