Set focus on first invalid input in AngularJs form

angularjs, angularjs-directive, validation, wcag

Solution

You can also use angular.element

angular.element('input.ng-invalid').first().focus();

View

<form name="myForm" novalidate="novalidate" data-ng-submit="myAction(myForm.$valid)" autocomplete="off"></form>

Controller

$scope.myAction= function(isValid) {
    if (isValid) {
        //You can place your ajax call/http request here
    } else {
        angular.element('input.ng-invalid').first().focus();
    }
};

used ngMessages for validation

The no jquery way

angular.element($document[0].querySelector('input.ng-invalid')).focus();

When using this method, need to pass `$document` as parameter in your angular controller

angular.module('myModule')
.controller('myController', ['$document', '$scope', function($document, $scope){
    // Code Here
}]);

Problem

I've read several articles and StackOverflow questions relating to the setting of focus in AngularJs. Unfortunately all the examples that I have read assume that there is some attribute that I can add to the element to gain focus, e.g. a focusMe directive. However what if I don't know in advance which input to set focus to? In particular how do I set focus to the first input element in a form that has $invalid set - i.e. an element that fails validation. There could be several inputs that fail validation, so I cannot use a directive that just tries to call .focus() based on this. (I am doing this for Accessibility/WCAG reasons, its good practice to do so on submit being clicked to minimize keypresses to find the first field that has failed validation). The $error object will give all controls that fail validation, but they are grouped by the type of failure not in any order of appearance on the form. I'm sure I can come up with some kludged way of doing this. A directive on the form, which receives some broadcast when focus needs to be set - that directive can then search for the first $invalid element. However this seems very complex and I'd like to know whether these is a better more 'angular' way of doing this.

Original source

Related problems