2

I am trying to get an Angular Directive to control setting the focus on an element programmatically.

Here is what my directive looks like in the component html:

<input type="text" class="form-control"
    [(ngModel)]="inputText" [myFocus]="isFocused">

Here is what my directive looks like:

import { Directive, OnInit, ElementRef, Renderer2, Input } from '@angular/core';

@Directive({
  selector: '[myFocus]'
})
export class FocusDirective implements OnInit {

  @Input('myFocus') isFocused: boolean;

  constructor(private hostElement: ElementRef, private renderer: Renderer2) { }

  ngOnInit() {
    if(this.isFocused) {   
      this.renderer.selectRootElement(this.hostElement.nativeElement).focus();
    }
  }
}

Then in the component code I changed this:

this.isFocused = true;

The directive is included in the app.module.ts like so:

import { FocusDirective } from './directives/focus.directive';

@NgModule({
  declarations: [
    FocusDirective
  ],
   bootstrap: [AppComponent]
})
export class AppModule { }

However the focus does not seem to get set when I do this. I understand there have been some fairly big changes to how the Renderer2 works, and I assume I am getting something wrong with my step of setting the focus in the ngOnInit() method.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Tom O'Brien
  • 1,741
  • 9
  • 45
  • 73
  • Possible duplicate of [How to set focus on element with binding?](https://stackoverflow.com/questions/38307060/how-to-set-focus-on-element-with-binding) – Jota.Toledo Nov 04 '18 at 13:39

2 Answers2

4

You can achieve using nativeElement.focus()

import { Directive, OnInit, ElementRef, Renderer2, Input } from '@angular/core';

@Directive({
  selector: '[myFocus]'
})
export class FocusDirective implements OnInit {

  @Input('myFocus') isFocused: boolean;

  constructor(private hostElement: ElementRef, private renderer: Renderer2) { }

  ngOnChanges() {
    if(this.isFocused) {   
      this.hostElement.nativeElement.focus();
    }
  }
}
Suresh Kumar Ariya
  • 9,516
  • 1
  • 18
  • 27
1

Simplified version of @Suresh Kumar Ariya's answer without using change detection. This will focus only when the [myFocus]=value directive switch to true.

import { Directive, ElementRef, Input } from '@angular/core';

@Directive({
  selector: '[myFocus]',
})
export class FocusDirective {
  constructor(private hostElement: ElementRef) {}

  @Input()
  set myFocus(focus: boolean) {
    if (focus) {
      this.hostElement.nativeElement.focus();
    }
  }
}
Flavien Volken
  • 19,196
  • 12
  • 100
  • 133