AngularJS - input autofocus with ng-if not working
Solution 1
The problem is the attribute autofocus
isnt an Angular directive. It is a browser supported specification of the <input>
element. If you want this to work as intended across multiple browsers and auto focus every time you click hide/show you will need to make a directive.
I took this directive right off Github Gist, credit to mlynch for building this directive.
Heres a working example of your application
angular
.module('App', [
'utils.autofocus',
]);
/**
* the HTML5 autofocus property can be finicky when it comes to dynamically loaded
* templates and such with AngularJS. Use this simple directive to
* tame this beast once and for all.
*
* Usage:
* <input type="text" autofocus>
*
* License: MIT
*/
angular.module('utils.autofocus', [])
.directive('autofocus', ['$timeout', function($timeout) {
return {
restrict: 'A',
link : function($scope, $element) {
$timeout(function() {
$element[0].focus();
});
}
}
}]);
<!DOCTYPE html>
<html ng-app="App">
<head ng-init="view={}; view.show = true">
<script data-require="[email protected]" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<button ng-click="view.show = !view.show">{{view.show ? "hide" : "show"}}</button>
</body>
<div ng-if="view.show">
<input autofocus />
</div>
<script src="script.js"></script>
</html>
Solution 2
You can use a directive for this. Plunker Demo
angular.module('myApp', []).directive('focusMe', function($timeout) {
return {
scope: {
focusMeIf:"="
},
link: function ( scope, element, attrs ) {
if (scope.focusMeIf===undefined || scope.focusMeIf) {
$timeout( function () { element[0].focus(); } );
}
}
};
});
You could also define a condition in it in focus-me-if
attribute in it.
Hope it helps.
cheziHoyzer
Updated on June 15, 2022Comments
-
cheziHoyzer almost 2 years
When I surround my
input
withng-if
, after hide and show theautofocus
attribute does not take effect:Here is the code:
<!DOCTYPE html> <html ng-app> <head> <script data-require="[email protected]" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body ng-init="view={}; view.show = true"> <button ng-click="view.show = !view.show">{{view.show ? "hide" : "show"}}</button> <div ng-if="view.show"> <input autofocus /> </div> </body> </html>
And here is the plunker: http://plnkr.co/edit/k7tb3xw5AsBYrhdlr3bA?p=preview
Just click on hide and after that on show and you will see the autofocus does not working!
In Chrome is working only on the first show, in FF and IE it's not working at all!
-
cheziHoyzer about 8 yearsFixed the demo, this is not the issue, tested on IE11. you can test it. it's not working
-
Radek Anuszewski about 7 yearsI would like to add one thing to your solution - prefix for directive. Like registering as
abcAutofocus
indirective(...)
as using asabc-autofocus
in HTML template to avoid confusing which solution is used - pure HTML or Angular directive. -
Soldeplata Saketos over 6 yearsGreaaaaaat solution. Thanks
-
Philipp Wirth over 3 yearsalternative would be to call
angular.element('[autofocus]').trigger('focus');
manually after button was clicked or response received