9

At the end of a method, I'll be clearing some fields, which is easy enough:

this.modelname.fieldname1 = "";
this.modelname.fieldname2 = "";

After clearing the fields, I'd like the cursor to appear in field1.

Is there an Angular2 way to do this, or do I just use old fashioned Javascript?

Brett Wolfington
  • 6,587
  • 4
  • 32
  • 51
mojo-jojo
  • 145
  • 1
  • 1
  • 7

5 Answers5

30

It is not recommended to access dom directly in Angular. Angular provides Renderer (Angular2) and Renderer 2(Angular4) abstractions.

Here is how to do in Angular 2:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <input #inp id="myInput" type="text">
      <button (click)="setFocus()">Set Focus</button>
    </div>
  `,
})
export class App {
  @ViewChild('inp') inp:ElementRef;

  constructor(private renderer: Renderer) {
  }

  setFocus() {
    this.renderer.invokeElementMethod(this.inp.nativeElement, 'focus');
  }
}

In Angular4 Renderer is depricated and Renderer2 is added. invokeElementMethod got removed and there is a discussion about it: https://github.com/angular/angular/issues/13818#issuecomment-297815331

Here is Angular 4 way:

 let onElement = this.renderer2.selectRootElement('#myInput');
 onElement.focus();
Julia Passynkova
  • 17,256
  • 6
  • 33
  • 32
  • 2
    Plus one for mentioning about the deprecated `invokeElementMethod` – Gangadhar Jannu Apr 29 '17 at 06:32
  • Two more references: https://stackoverflow.com/questions/42996481/how-to-focus-on-a-field-in-angular and https://github.com/angular/angular/issues/15674 – Felix May 29 '18 at 08:18
  • The selectRootElement('#myInput') did not work for me (could not locate the element) but I suppose because I had this @ViewChild('myInput') input: ElementRef; at the top. But @candidJ solution worked for me. Do you have any idea why ? – Investigator Nov 16 '18 at 10:21
  • and how would it be in a list of inputs? In an email list, but I want to edit what's in position 2, and I want to focus on it – Alex Alan Nunes Sep 05 '21 at 15:52
21

You can use a template reference variable in the first input, that will give you the ability to run .focus() on it.

In your template you can add #fieldName1 to your input tag (i.e. <input type="text" #fieldName1>)

in your controller do:

@ViewChild('fieldName1')
fieldName1: any;

now you can do this.fieldName1.nativeElement.focus() in the controller or fieldName1.focus() in the template.

Ahmed Musallam
  • 9,523
  • 4
  • 27
  • 47
Jose Zamudio
  • 865
  • 1
  • 8
  • 22
6

Adding renderer way using @ViewChild decorator. You can skip using #id attribute as mentioned by @julia above.

It will focus input element once the view is initialized Html:

<textarea  #tasknote name="tasknote"> </textarea> 

JS:

export class MyComponent implements AfterViewInit {
      @ViewChild('tasknote') input: ElementRef;
         constructor(private renderer: Renderer2){           
          }

       ngAfterViewInit() {
       //using selectRootElement instead of deprecated invokeElementMethod
       this.renderer.selectRootElement(this.input["nativeElement"]).focus();
      }

    }

to know more about other functions of renderer follow official docs

candidJ
  • 4,289
  • 1
  • 22
  • 32
1

Taking inspiration from How to set focus on input field? I achieved this by creating an attribute directive that set the focus of the element. This meant that I didn't need to reference elements directly in my component controller and it supports binding.

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

@Directive({
    selector: "[appFocusMe]"
})
export class FocusMeDirective {

    @Input("appFocusMe") set focusElement(focus: boolean) {
        if (focus) {
            this.el.nativeElement.focus();
        }
    }

    constructor(private el: ElementRef) { }
}

And then in the view:

<input [appFocusMe]="true" />
Simon Stanford
  • 353
  • 3
  • 10
0

simple way

 <input type="text" id="updateField" >

js/ts

   let element=document.getElementById('updateField');
             element.focus();  

use in setTimeOut if you get undefinded error

 setTimeout(()=>{
                 let element=document.getElementById('updateField');
                 element.focus();                 
             },100)
Shahid Islam
  • 559
  • 3
  • 7