How to set focus on an element with binding?

In Angular2, how to set the binding for the focus of an element. I do not want to set it using elementRef. I think that in AngularJS there is a ngFocus directive. In Angular2 there is no such directive

+11
source share
9 answers

The rendering service is now deprecated (starting with Angular 4.x) The new Renderer2 service does not have invokeElementMethod. What you can do is get a link to an element like this:

const element = this.renderer.selectRootElement('#elementId'); 

And then you can use this to focus on this element as follows:

 element.focus(); 

More on how selectRootElement works here :

EDIT:

If the element does not focus, the general problem is that the element is not ready. (for example: disabled, hidden, etc.). You can do it:

 setTimeout(() => element.focus(), 0); 

This will create a macro task that will be executed in the next turn of the virtual machine, so if you turn on the element, the focus will work correctly.

+18
source

Simple focus directive

 import {Directive, Input, ElementRef} from 'angular2/core'; @Directive({ selector: '[focus]' }) class FocusDirective { @Input() focus:boolean; constructor(@Inject(ElementRef) private element: ElementRef) {} protected ngOnChanges() { this.element.nativeElement.focus(); } } // Usage @Component({ selector : 'app', template : ' <input [focus]="inputFocused" type="text"> <button (click)="moveFocus()">Move Focus</button> ', directives: [FocusDirective] }) export class App { private inputFocused = false; moveFocus() { this.inputFocused = true; // we need this because nothing will // happens on next method call, // ngOnChanges in directive is only called if value is changed, // so we have to reset this value in async way, // this is ugly but works setTimeout(() => {this.inputFocused = false}); } } 
+14
source

I tried both options, but no one is suitable for simple use. 1st (by @AngJobs) needs additional work in the component where you use the directive (to set focus = true), 2nd (by @ShellZero) does not work at all, because the focus that is called before the view is really ready. So I moved the focus to ngAfterViewInit . Now you can just add <input focus... and forget about it. The item will automatically receive focus after automatic viewing.

 import { Directive, ElementRef, Renderer, AfterViewInit } from '@angular/core'; @Directive({ selector: '[focus]' }) export class DmFocusDirective implements AfterViewInit { constructor(private _el: ElementRef, private renderer: Renderer) { } ngAfterViewInit() { this.renderer.invokeElementMethod(this._el.nativeElement, 'focus'); } } 
+9
source

The best way to adjust focus on an element using angular2 is to use a Renderer and call the method on the element. There is no way to do this without elementRef .

The result is approximately the following:

 this.renderer.invokeElementMethod(this.input.nativeElement, 'focus', []); 

Where Renderer is entered into the constructor using protected renderer : Renderer

+2
source

Much simpler:

 import { Directive, ElementRef, Renderer} from "@angular/core"; @Directive({ selector: "[Focus]" }) export class myFocus { constructor(private _el: ElementRef, private renderer: Renderer) { this.renderer.invokeElementMethod(this._el.nativeElement, 'focus'); } } 
+1
source

It works for me, but has errors in the console. After debugging and searching, this article was found: https://www.picnet.com.au/blogs/guido/post/2016/09/20/angular2-ng2-focus-directive/

Just copy-paste. This worked great for me.

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

From @MrBlaise I took a snippet of setTimeout, which did the following work for me.

 <input type="text" #searchInput /> import { ElementRef, ViewChild } from '@angular/core'; ... @ViewChild('searchInput') private searchInput: ElementRef; ... setTimeout(() => this.searchInput.nativeElement.focus(), 0); 
+1
source
 import { Directive, ElementRef, AfterViewChecked } from '@angular/core'; @Directive({ selector: '[autoFocus]', }) export class FocusDirective implements AfterViewChecked { constructor(private _elementRef: ElementRef) { } ngAfterViewChecked() { this._elementRef.nativeElement.focus() } } 
0
source

The trick is to use both tricks and choose together:

. This (element) .nativeElement.focus (); . This (element) .nativeElement.select ();

0
source

All Articles