How to set focus on input field?

2018-12-31 02:50发布

What is the 'Angular way' to set focus on input field in AngularJS?

More specific requirements:

  1. When a Modal is opened, set focus on a predefined <input> inside this Modal.
  2. Everytime <input> becomes visible (e.g. by clicking some button), set focus on it.

I tried to achieve the first requirement with autofocus, but this works only when the Modal is opened for the first time, and only in certain browsers (e.g. in Firefox it doesn't work).

Any help will be appreciated.

30条回答
无与为乐者.
2楼-- · 2018-12-31 03:42

I have found some of the other answers to be overly complicated when all you really need is this

app.directive('autoFocus', function($timeout) {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            $timeout(function(){
                _element[0].focus();
            }, 0);
        }
    };
});

usage is

<input name="theInput" auto-focus>

We use the timeout to let things in the dom render, even though it is zero, it at least waits for that - that way this works in modals and whatnot too

查看更多
深知你不懂我心
3楼-- · 2018-12-31 03:42

HTML has an attribute autofocus.

<input type="text" name="fname" autofocus>

http://www.w3schools.com/tags/att_input_autofocus.asp

查看更多
听够珍惜
4楼-- · 2018-12-31 03:42

It's easy.. try this

html

<select id="ddl00">  
 <option>"test 01"</option>  
</select>

javascript

document.getElementById("ddl00").focus();
查看更多
只若初见
5楼-- · 2018-12-31 03:43

I found it useful to use a general expression. This way you can do stuff like automatically move focus when input text is valid

<button type="button" moo-focus-expression="form.phone.$valid">

Or automatically focus when the user completes a fixed length field

<button type="submit" moo-focus-expression="smsconfirm.length == 6">

And of course focus after load

<input type="text" moo-focus-expression="true">

The code for the directive:

.directive('mooFocusExpression', function ($timeout) {
    return {
        restrict: 'A',
        link: {
            post: function postLink(scope, element, attrs) {
                scope.$watch(attrs.mooFocusExpression, function (value) {

                    if (attrs.mooFocusExpression) {
                        if (scope.$eval(attrs.mooFocusExpression)) {
                            $timeout(function () {
                                element[0].focus();
                            }, 100); //need some delay to work with ng-disabled
                        }
                    }
                });
            }
        }
    };
});
查看更多
孤独寂梦人
6楼-- · 2018-12-31 03:44

I don't think $timeout is a good way to focus the element on creation. Here is a method using built-in angular functionality, dug out from the murky depths of the angular docs. Notice how the "link" attribute can be split into "pre" and "post", for pre-link and post-link functions.

Working Example: http://plnkr.co/edit/Fj59GB

// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
    return {
        link: {
            pre: function preLink(scope, element, attr) {
                console.debug('prelink called');
                // this fails since the element hasn't rendered
                //element[0].focus();
            },
            post: function postLink(scope, element, attr) {
                console.debug('postlink called');
                // this succeeds since the element has been rendered
                element[0].focus();
            }
        }
    }
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />

Full AngularJS Directive Docs: https://docs.angularjs.org/api/ng/service/$compile

查看更多
伤终究还是伤i
7楼-- · 2018-12-31 03:46

Just a newbie here, but I was abble to make it work in a ui.bootstrap.modal with this directive:

directives.directive('focus', function($timeout) {
    return {
        link : function(scope, element) {
            scope.$watch('idToFocus', function(value) {
                if (value === element[0].id) {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});

and in the $modal.open method I used the folowing to indicate the element where the focus should be putted:

var d = $modal.open({
        controller : function($scope, $modalInstance) {
            ...
            $scope.idToFocus = "cancelaAteste";
    }
        ...
    });

on the template I have this:

<input id="myInputId" focus />
查看更多
登录 后发表回答