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

Image for post
Image for post
Photo by Kevin Ku on Unsplash

There’s more than one way to skin a cat. While not the best metaphor, admittedly, it always holds true in programming. Don’t worry, though, this isn’t a disgusting article about cat-skinning methods and which are best. It’s a disgusting article showcasing another, more “Angular” way to set auto-focus on input fields throughout your Angular application.

First thing’s first, you’ll want to fire up a new Angular application.

Next, we’ll be creating an Angular Directive. A directive, or attribute directive, changes the appearance or behavior of a DOM element. There are 3 kinds of directives: Components, Structural and Attribute directives. In our case, we’ll be setting focus on an element, so that’s an attribute directive. Using NgIf or NgFor to render elements is an example of Structural elements (Read more).

Before creating our directive, add the following VSCode extension: Angular Schematics. As of writing this, the current version is 4.5.0, but it shouldn’t make much of a difference.

Now, right-click on our “app” folder and select the option “Angular: Generate another schematic”. Then, choose “directive” as the type of schematics you wish to generate. For simplicity sake, name it “autofocus”. Click Enter, then Confirm.

You should see 2 new files in the app directory:

  1. autofocus.directive.spec.ts
  2. autofocus.directive.ts

Open the autofocus.directive.ts file and let’s code our directive!

We’ll need an input, so within the Class, just before the constructor, add the following:

Next, we’ll inject an ElementRef into our constructor. This is so we can have a reference to the input field(s) that we’ll use our directive on. Your constructor should look like this:

To actually set focus on the element, we’ll use Angular’s ngAfterContentInit. This is a lifecycle event that is called after a directive’s content has been fully initialized.

We need to have our class implement this, like so:

Lastly, we’ll code our ngAfterContentInit logic, which is a setTimeout function that runs every 500 milliseconds and tries to set focus onto the element. This is because we need to give Angular time to draw the element onto the screen before we can set focus.

The entire file should look like this:

Image for post
Image for post
Angular autofocus Directive

To use the directive, we’ll go to our app.component.html file and clear the contents. Next, add a basic input field and use the selector for our autofocus directive, which is “appAutoFocus”, as seen above:

If you serve your application, when it loads, the input field should be auto-focused.

We can even test a scenario whereby the input field is not drawn/rendered immediately, but when a button is clicked. To do that, replace the contents of your app.component.html file with the following:

Now we have a button that either shows or hide the input field. When it is shown, it should be auto-focused.

Add the following to your app.component.ts file for it to show/hide the :

Image for post
Image for post

Side Note:

After creating the directive, and coding its logic, you may get an error in your .spec file. This error is just because you need to create a mock element in it for testing purposes, but it should not affect your ability to serve the app. If it does both you, replace the line with the definition of the directive with this in your spec file:

Written by

Interested in Computer Science, education and world domination.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store