siannone
siannone

Reputation: 6763

Can't focus input in AngularJS

I'm trying to focus an input box with AngularJS. To achieve that I created a custom directive, but for some reasons it doesn't work on a particular input box.

This is my 'focus' directive:

angular.module('app.ui.input').directive('ooFocus', function()
{
    return {
        scope : {
            trigger : '=ooFocus'
        },
        restrict : 'A',
        link : function(scope, element, attrs)
        {
            scope.$watch('trigger', function(value)
            {
                if(value)
                {
                    console.log('this will be printed');
                    element[0].focus();
                    element[0].select();
                }
            });
        }
    }
});

And this is how it looks like when it's being applied to the input box:

<input placeholder="Company name" type="text" ng-model="company.name" ng-blur="hide()" oo-focus="show" required>

The form containing the input box is hidden and it's displayed when show is set to true. show is passed to the oo-focus directive and I can see that the directive is printing this will be printed in the console whenever show is set to true, but for some reasons the input is not focused.

Upvotes: 3

Views: 2209

Answers (2)

Sulthan
Sulthan

Reputation: 130082

You can't focus what's hidden, it's as simple as that. So you have to be sure that your input is displayed before trying to focus it.

The problem is that usually you are not working with css directly, which would show the element immediately. Usually you are using a directive like ng-show or ng-if and you can't even be sure if they are evaluated before ooFocus.

Using $timeout to delay the focus is a good solution for such a situation.

Upvotes: 3

Alhuck
Alhuck

Reputation: 1029

I have one work around for this. Try using $timeout inside directive like this,

.directive('ooFocus',function($timeout) {
return {
    scope : {
        trigger : '=ooFocus'
    },
    restrict : 'A',
    link : function(scope, element) {

        scope.$watch('trigger', function(value) {
          if (value) {
            $timeout(function() {
                element[0].focus();
            });
          }
        });
    }
};

});

Upvotes: 1

Related Questions