Angular2 (NG2) Focus Directive

by Guido Tapia

in software-engineering,

September 20, 2016

Requesting focus on an input field is surprisingly hard in angular2. Especially when the input field is inside a dialog or an *ngIf that is not initially visible.

After much trial and error this is the solution I came up with. It works on my machine and my scenarios, no other guarantees provided:

import {Directive, AfterViewInit, ElementRef, DoCheck} from '@angular/core';
@Directive({ selector: '[autofocus]' }) export class Autofocus implements AfterViewInit, DoCheck { private lastVisible: boolean = false; private initialised: boolean = false; constructor(private el: ElementRef) {}
ngAfterViewInit() { this.initialised = true; this.ngDoCheck(); }
ngDoCheck() { if (!this.initialised) { return; } const visible = !!this.el.nativeElement.offsetParent; if (visible && !this.lastVisible) { setTimeout(() => { this.el.nativeElement.focus(); }, 1); } this.lastVisible = visible; } }

This directive hooks into the change detection loop and on iteration checks whether the input element marked with the attribute `[autofocus]` has become visible. If so then we request focus.

It appears to work, however there may be scenarios and edge cases where this approach is too simplistic. Give it a go and let me know how it goes.