Thad Peiffer
Thad Peiffer

Reputation: 638

AngularJS - setting focus to element using NON-ISOLATE directive

I know this question has been asked about 100 times (trust me, I've read them all), but I'm having trouble getting focus to go to an input box when the directive does NOT use isolate scope. The scope.$watch doesn't fire when the backing data changes.

Why not just use the one with isolate scope, you ask? Well, my understanding is that you should ONLY use isolate scope if your directive has a template.

The only differences in the directives is:

// works
app.directive('doesFocus', function ($timeout) {
    return {
        scope: { trigger: '@doesFocus' },
        link: function (scope, element) {
            scope.$watch('trigger', function (value) {
              // sets focus
            }
            ...

// does not work, and in fact when I inspect attrs.doesNotFocus it is undefined
app.directive('doesNotFocus', function ($timeout) {
    return {
        scope: false,
        link: function (scope, element, attrs) {
            scope.$watch(attrs.doesNotFocus, function (value) {
              // sets focus
            }
            ...

I'm on week 3 of using Angular, so I must be missing some silly semantic issue.

Here is a fiddle illustrating my issue. http://jsfiddle.net/tpeiffer/eAFmJ/


EDIT

My actual problem was that my real code was like this (hazard of mocking the problem, you sometimes mask the real problem):

<input should-focus="{{isDrawerOpen()}" ... ></input>

but because I was using a function, not a property, I was missing the required ticks

<input should-focus="{{'isDrawerOpen()'}}" ... ></input>

Making this change fixed the problem and my directive can still be like this:

scope.$watch(attrs.shouldFocus, focusCallback(newValue));

END EDIT


Thanks for helping me in my quest for angular excellence!

Thad

Upvotes: 0

Views: 652

Answers (2)

Mark Rajcok
Mark Rajcok

Reputation: 364727

Remove {{}} from your HTML. So instead of:

<input class="filter-item" placeholder="Enter filter" 
 does-not-focus="{{bottomDrawerOpen}}" type="text">

use

<input class="filter-item" placeholder="Enter filter" 
 does-not-focus="bottomDrawerOpen" type="text">

Then it works with watching attrs.doesNotFocus:

scope.$watch(attrs.doesNotFocus, function (value) {...} );

Fiddle

Upvotes: 1

mitch
mitch

Reputation: 1831

Your bottom drawer was watching a function isDrawerOpen(), not a property.
Change

   scope.$watch('isDrawerOpen()',...);

to

   scope.$watch('toggleBottomDrawer',...);

Upvotes: 0

Related Questions