set focus in input element after submit and reset form
Asked Answered
C

4

12

I'm working with a template form component with angular2 and I cannot get to set the focus in my firstName input element after submit the form. The form is reseted fine but no way of setting focus.

This is my component code:

export class TemplateFormComponent {

  @ViewChild('f') form: any;

  onSubmit() {
    if (this.form.valid) {
      console.log("Form Submitted!");
      this.form.reset();
      this.form.controls.firstName.focus();
    }
  }
}

and my template code:

<form novalidate autocomplete="off" #f="ngForm" (ngSubmit)="onSubmit()">
<div class="form-group">
  <label>First Name</label>
  <input type="text"
         class="form-control"
         name="firstName"
         [(ngModel)]="model.firstName"
         required
         #firstName="ngModel">
</div>
</form>
Chorea answered 29/3, 2017 at 18:17 Comment(0)
L
15

On your view, set a reference to the input field you want to focus (you already have that with #firstName).

Then, on your component code, create an access to it with @ViewChild:

@ViewChild('firstName') firstNameRef: ElementRef;

And finally, right after reseting the form:

this.firstNameRef.nativeElement.focus()

ps.: I would expect the FormControl api to expose a focus method, but this issue on gitHub suggests it may never happen.

Lunation answered 28/6, 2017 at 13:2 Comment(1)
This doesn't seem to work anymore as of today, you will get a ERROR TypeError: Cannot read property 'focus' of undefined. I solved adding in the template a second reference to the input element (#firstNameRef) and calling @ViewChild('firstNameRef') firstNameRef: ElementRef;Davin
X
2

For a more generic solution see

Is it possible to get native element for formControl? `

@Directive({
    selector: '[ngModel]',
})
export class NativeElementInjectorDirective {
    constructor(private el: ElementRef, private control : NgControl) {
        (<any>control.control).nativeElement = el.nativeElement;
    }
}

`

This will add the nativeElement to EACH form control once you add the directive to your module.

UPDATE: a much simpler solution for this usecase To set focus on the first invalid element on a form create a directive like this:

import { Directive, HostListener, ElementRef} from '@angular/core';

@Directive({
  selector: '[focusFirstInvalidField]'
})
export class FocusFirstInvalidFieldDirective {

  constructor(private el: ElementRef) { }

  @HostListener('submit')
  onFormSubmit() {
    const invalidElements = this.el.nativeElement.querySelectorAll('.ng-invalid');
    if (invalidElements.length > 0) {
      invalidElements[0].focus();
    }
  }
}

Then simply add it to your form element tag

Xyster answered 28/9, 2018 at 13:28 Comment(0)
T
0

Simple solution: add "autofocus" to your input element properties.

<input type="text" class="form-control" name="firstName" autofocus required>
Turning answered 12/7, 2021 at 20:50 Comment(0)
N
0

Maybe not so Angularish, but i works (in all kinds of javascript environments).

In HTML:

<input id="inputFirstName" type="text" class="form-control" name="firstName">

And in the component:

  ngAfterViewChecked() {
    document.getElementById('inputFirstName')?.focus();
  }
Nursery answered 13/2 at 9:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.