0

I have a front-end angular app in which I would like to have the focus set to a particular textarea with the cursor blinking and ready to have the user type in the text area upon loading.

After doing some Googling I thought that @ViewChild might be the way to go. But so far I have been able to get it to work.

Here is my entire self-contained ts file:

import { Component, ElementRef, ViewChild } from '@angular/core';


@Component({
  selector: 'my-app',
  template: `
    <h1>Hello from {{name}}!</h1>
    <textarea #reference placeholder="Start typing"></textarea>
  `
})
export class App {

  @ViewChild('reference') textarea: ElementRef<HTMLTextAreaElement> | undefined;
  name = 'Angular';

  ngAfterViewInit(): void {
    this.textarea?.nativeElement.focus();
  }

}
Tim
  • 443
  • 2
  • 5
  • 13
  • Aren't you getting any error in the console ? The viewchild is likely undefined before `afterViewInit()` – Matthieu Riegler Jun 29 '23 at 22:01
  • No, no error in the console or anywhere else. Everything comes up okay - just without any focus to the text area or anywhere else. – Tim Jun 29 '23 at 22:09
  • I did try putting the this.myInputField.nativeElement.focus(); in the ngAfterViewInit though. Still no focus. – Tim Jun 29 '23 at 22:15

3 Answers3

1

The first thing is to pass correct options to @ViewChild:

@ViewChild('myinput', {read: ElementRef})

otherwise you will get component instance instead of dom node.

If you don't have any structural directives like *ngIf/*ngFor then you can also pass {static: true, read: ElementRef}, it will make elementRef available in ngOnInit, otherwise you have to use AfterViewInit

kemsky
  • 14,727
  • 3
  • 32
  • 51
0

You want to use the ngAfterViewInit lifecycle hook

https://angular.io/guide/lifecycle-hooks

Respond after Angular initializes the component's views and child views, or the view that contains the directive. See details and example in Responding to view changes in this document.

Stackblitz: https://stackblitz.com/edit/stackblitz-starters-8evga1?file=src%2Fmain.ts

Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
  • Thanks - is it just a matter of doing the this.myInputField.nativeElement.focus(); within the ngAfterViewInit function? I've tried doing it there - and also in other functions that aren't triggered until after the form loads. Still no luck. – Tim Jun 29 '23 at 22:32
  • @Tim - I've added a stackblitz to show how it works, if you can't get it to work can you provide a reproducible example of what you've tried? – Adam Jenkins Jun 29 '23 at 22:41
  • Thanks for the suggestions everyone. I'm not sure why it just doesn't want to focus. I pasted my updated code above to follow the stackblitz example. Still just won't focus. – Tim Jun 30 '23 at 06:44
-1

I think the code isn't working because the nativeElement isn't in the DOM yet. The following works (and you should see in the console (test1) that nativeElement is null at the beginning of ngAfterViewInit). Maybe that you have to increase the 1000ms:

ngAfterViewInit(): void {
    // nativeElement is null
    console.log('test1',this.textarea?.nativeElement);
    setTimeout(() => {
            // nativeElement is not null
            console.log('test2',this.textarea?.nativeElement);
            this.textarea?.nativeElement.focus();
}, 1000);

}

A more deterministic way (than the setTimeout) to wait for a nativeElement to appear in the DOM is described here: Make function wait until element exists

FrankL
  • 374
  • 4
  • 5