I've taken a bootstrap directive that watches all the input elements on a form and updates the CSS of its parent div to show validation errors in a Bootstrap way. The watch looks at the elements css class and if ng-invalid is present it adds has-error to the parent.

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 original directive was taken from an answer on S.O. I think the original answer derives from this Reconcile Angular.js and Bootstrap form validation styling but someone took it and expanded on it and I can't find their answer. It also takes more code from this show validation error messages on submit in angularjs to handle preventing the form being submitted but I'm omitting that for now

The directive works fine when using synchronous validators but when I use an async validator it gets the validation states mixed up. After making the field invalid, the watch fires but input.hasClass('ng-invalid') returns false . I'm at a loss about why it might happen.

I've created a plunkr here http://plnkr.co/edit/0wUUPdZc0fYN6euvsIMl?p=preview