Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2+ autofocus input element

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.

like image 467
Makla Avatar asked Jan 26 '17 12:01

Makla


People also ask

What is AutoFocus attribute in HTML?

Definition and Usage The autofocus attribute is a boolean attribute. When present, it specifies that the element should automatically get focus when the page loads.


1 Answers

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 
like image 74
Makla Avatar answered Sep 28 '22 09:09

Makla