[SOLVED] Angular2+ autofocus input element

Issue

How can I autofocus input element? Similar to this question, but not with AngularDart. Something like this:

<input type="text" [(ngModel)]="title" [focus] />
//or 
<input type="text" [(ngModel)]="title" autofocus />

Does Angular2 has any build in support for this feature?

Best close question is this one, but is there any shorter/easier solution, since I do not have “list of input boxes”. In provided link *ngFor="#input of inputs" is used, but I only have 1 input in control template.

Solution

This is my current code:

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

@Directive({
    selector: "[autofocus]"
})
export class AutofocusDirective
{
    private focus = true;

    constructor(private el: ElementRef)
    {
    }

    ngOnInit()
    {
        if (this.focus)
        {
            //Otherwise Angular throws error: Expression has changed after it was checked.
            window.setTimeout(() =>
            {
                this.el.nativeElement.focus(); //For SSR (server side rendering) this is not safe. Use: https://github.com/angular/angular/issues/15008#issuecomment-285141070)
            });
        }
    }

    @Input() set autofocus(condition: boolean)
    {
        this.focus = condition !== false;
    }
}

use case:

[autofocus] //will focus
[autofocus]="true" //will focus
[autofocus]="false" //will not focus

Outdated code (old answer, just in case):
I ended up with this code:

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

@Directive({
    selector: '[autofocus]'
})
export class Autofocus
{
    constructor(private el: ElementRef, private renderer: Renderer)
    {        
    }

    ngOnInit()
    {        
    }

    ngAfterViewInit()
    {
        this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }
}

If I put code in ngOnViewInit it does not work. Code also use best practices, since calling focus on element directly is not recommended.

Edited (conditional autofocus):
A few days ago I needed conditional auto focus, because I hide first autofocus element and I want to focus another, but only when first is not visible, and I ended with this code:

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

@Directive({
    selector: '[autofocus]'
})
export class AutofocusDirective
{
    private _autofocus;
    constructor(private el: ElementRef, private renderer: Renderer)
    {
    }

    ngOnInit()
    {
    }

    ngAfterViewInit()
    {
        if (this._autofocus || typeof this._autofocus === "undefined")
            this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }

    @Input() set autofocus(condition: boolean)
    {
        this._autofocus = condition != false;
    }
}

Edited2:
Renderer.invokeElementMethod is deprecated and new Renderer2 does not support it.
So we are back to native focus (which doesn’t work outside DOM – SSR for example!).

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

@Directive({
    selector: '[autofocus]'
})
export class AutofocusDirective
{
    private _autofocus;
    constructor(private el: ElementRef)
    {
    }

    ngOnInit()
    {
        if (this._autofocus || typeof this._autofocus === "undefined")
            this.el.nativeElement.focus();      //For SSR (server side rendering) this is not safe. Use: https://github.com/angular/angular/issues/15008#issuecomment-285141070)
    }

    @Input() set autofocus(condition: boolean)
    {
        this._autofocus = condition != false;
    }
}

use case:

[autofocus] //will focus
[autofocus]="true" //will focus
[autofocus]="false" //will not focus

Answered By – Makla

Answer Checked By – Senaida (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *