Cory Rylan

My name is . Google Developer Expert, speaker, and Software Developer at VMware Clarity Design System.

Follow @coryrylan
Angular

Focus First Invalid Input with Angular Forms

Cory Rylan

- 2 minutes

This article has been updated to the latest version Angular 12 and tested with Angular 11. The content is likely still applicable for all Angular 2 + versions.

When dealing with required inputs on a form sometimes the user can miss a required field. When this happens, it can be confusing for users what needs to be resolved to continue in the form. With Angular Forms, we can help the user by focusing the first invalid input when they submit the form.

In this example form, we have two inputs. Each input has a required validator to ensure the user has entered a value.

<form [formGroup]="form" (ngSubmit)="submit()">
<label for="first">First Name</label>
<input formControlName="first" id="first" />

<label for="last">Last Name</label>
<input formControlName="last" id="last" />

<button>submit</button>
</form>
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;

constructor(private formBuilder: FormBuilder) {
this.form = this.formBuilder.group({
first: ['', Validators.required],
last: ['', Validators.required]
});
}

submit() {
if (this.form.valid) {
console.log(this.form);
}
}
}

Our form is using Angular Reactive Forms and the FormBuilder service to create the logic for our form. To add the logic to focus the first invalid input when the user submits, we will create an isolated directive. This directive we will call focusInvalidInput. When this directive is placed on our form it will listen for the submit event to know when to focus our first invalid input.

import { Directive, HostListener, ElementRef } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { FormGroup } from '@angular/forms';

@Directive({
selector: '[focusInvalidInput]'
})
export class FormDirective {
constructor(private el: ElementRef) {}

@HostListener('submit')
onFormSubmit() {
const invalidControl = this.el.nativeElement.querySelector('.ng-invalid');

if (invalidControl) {
invalidControl.focus();
}
}
}

To listen to the submit event on our form element, we can use the @HostListener decorator to call our method when fired. Once we have the event, we can check if there are any invalid inputs. The easiest way to check for invalid inputs is to check for the .ng-invalid CSS selectors that are created in the HTML by Angular.

To check the template of just our form, we can inject the ElementRef service which will provide a reference to our HTML form template. With the template we can use this.el.nativeElement.querySelector('.ng-invalid') to get a list of invalid inputs. If there are any invalid elements, we can then focus the first one in the list.

Once we have the directive created, we need to make sure we place it on the form element that we want the behavior.

<form focusInvalidInput [formGroup]="form" (ngSubmit)="submit()">
<label for="first">First Name</label>
<input formControlName="first" id="first" />

<label for="last">Last Name</label>
<input formControlName="last" id="last" />

<button>submit</button>
</form>

If you want this behavior by default globally for all forms in your Angular application you can change the directive selector from [focusInvalidInput] to form Check out the full working demo below!

View Demo Code   
 

No spam. Short occasional updates on Web Development articles, videos, and new courses in your inbox.

Related Posts

VMWare Clarity

Building forms with Angular and Clarity Design

Learn how to create high-quality forms using Angular and the Clarity Design System.

Read Article
Angular

Using HTML5 Date Input with Date Objects and Angular

Learn how to use JavaScript Date Objects with the native HTML5 datepicker and Angular Forms.

Read Article
Angular

Measuring Angular Performance with Source Map Explorer

Learn how to identify performance bottlenecks in your Angular application with the Source Map Explorer tool.

Read Article