Recently, I implemented a bootstrap directive that monitors all the input elements on a form and updates the CSS of its parent div to display validation errors in a Bootstrap-friendly manner. The directive checks for the presence of the ng-invalid class in the elements' CSS and adds has-error to the parent if found.
element.find('.form-group').each(function () {
var formGroup = $(this);
var inputs = formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if (inputs.length > 0) {
inputs.each(function () {
var input = $(this);
scope.$watch(function () {
return input.hasClass('ng-invalid') && (!input.hasClass('ng-pristine') || form.$submitted);
}, function (isInvalid) {
formGroup.toggleClass('has-error', isInvalid);
});
});
}
});
The initial concept of this directive was borrowed from an answer on S.O., possibly originating from Reconcile Angular.js and Bootstrap form validation styling, although it went through further enhancements by another contributor whose specific modifications I couldn't locate. In addition, aspects of the code were inspired by show validation error messages on submit in angularjs for handling form submission prevention but I haven't included that functionality here.
While this directive functions smoothly with synchronous validators, it encounters issues with async validators where the validation states become muddled. Upon marking a field as invalid, the watch triggers, however, input.hasClass('ng-invalid')
erroneously returns false
. This discrepancy leaves me perplexed regarding its root cause.
I've set up a plunkr demonstration available at http://plnkr.co/edit/0wUUPdZc0fYN6euvsIMl?p=preview