Auto-focusing an Angular Input — The Easy Way? (Part 1)

David McIntosh
3 min readJun 18, 2020
Photo by Stefan Cosma on Unsplash

Lately, a requirement came up for me to auto-focus an input field in one of our Angular sites. Normally, this would be a quick and easy task, and ultimately it wasn’t so hard, but it definitely wasn’t as straight-forward as you might think.

In Angular, it’s not as easy as just setting the “autofocus” on an HTML element, especially since Google Chrome tends to disable auto-focus. With recent Chrome updates, if you try to use the “autofocus” property on a field, you might see two things:

  1. It doesn’t always work.
  2. You might see a message in your console like this:
Autofocus processing was blocked because a document's URL has a fragment '#/login'.

This same property works on Firefox. If only we lived in a world where our users all used one browser (wishful thinking). Instead, we need to ensure it works everyone, whether it’s on Chrome, Firefox, Safari, DuckDuckGo, or some lesser-known browser.

So, fix it, then!

Let’s create a small Angular P-O-C (proof-of-concept) for this:

  1. Open up your fave code editor (mine’s Visual Studio Code) and create a new Angular project. You can call it “form-focus”.
ng new form-focus

2. Open the app.component.html and delete everything between the “div” with a class “Toolbar” and the “router-outlet”, then paste this code between them:

<div class="content" role="main">
<form class="example-form">
<mat-form-field class="example-full-width" >
<textarea #myinput matInput placeholder="We'll autofocus this element."
</textarea>
</mat-form-field>
</form></div>

Here, we define a new div, containing one form and a single textarea element to use as an input field we will focus. It’s important you give the textarea a unique id, which is why we add the “#myinput”.

This id alone won’t do anything, but the magic happens with what we do next!

3. Open app.component.ts, and ensure to import ViewChield and ElementRef from ‘@angular/core’. Your imports should be:

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

4. Now, within your AppComponent class, define an ngAfterViewInit() function with the following contents:

@ViewChild("myinput") myInputField: ElementRef;
ngAfterViewInit() {
this.myInputField.nativeElement.focus();
}

With this, we utilize Angular’s built-in function that ngAfterViewInit(). This is called when the page is loading and the elements have been defined on the page. If we used ngOnInit(), we would get an error when trying to access the input field, since it has not yet been defined, or “drawn” on the screen.

We use the ‘@ViewChild’ decorator to make a reference to the element in our HTML that has an id of “myinput” and store it in an ElementRef object called, myInputField. Within ngAfterViewInit(), we simply call the focus() function on our element reference, setting the focus on the element.

The contents of your app.component.ts file should be:

import { Component, ViewChild, ElementRef } from '@angular/core';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.scss']})export class AppComponent {
title = 'form-focus';
@ViewChild("myinput") myInputField: ElementRef;
ngAfterViewInit() {
this.myInputField.nativeElement.focus();
}
}

All that’s left is to start our application, using “ng serve — open” and you’ll see that the input field is focused when the page loads.

End Result

--

--

David McIntosh

Interested in Computer Science, education and world domination.