Here is an Angular4+ directive that you can re-use in any component. Based on code given in the answer by Niel T in this question.
import { NgZone, Renderer, Directive, Input } from '@angular/core';
@Directive({
selector: '[focusDirective]'
})
export class FocusDirective {
@Input() cssSelector: string
constructor(
private ngZone: NgZone,
private renderer: Renderer
) { }
ngOnInit() {
console.log(this.cssSelector);
this.ngZone.runOutsideAngular(() => {
setTimeout(() => {
this.renderer.selectRootElement(this.cssSelector).focus();
}, 0);
});
}
}
You can use it in a component template like this:
<input id="new-email" focusDirective cssSelector="#new-email"
formControlName="email" placeholder="Email" type="email" email>
Give the input an id and pass the id to the cssSelector
property of the directive. Or you can pass any cssSelector you like.
Comments from Niel T:
Since the only thing I'm doing is setting the focus on an element, I
don't need to concern myself with change detection, so I can actually
run the call to renderer.selectRootElement outside of Angular. Because
I need to give the new sections time to render, the element section is
wrapped in a timeout to allow the rendering threads time to catch up
before the element selection is attempted. Once all that is setup, I
can simply call the element using basic CSS selectors.