How to get ElementRef reference from NgModel FormControl in NgForm in Angular 4+

asmmahmud picture asmmahmud · Nov 28, 2017 · Viewed 9.9k times · Source

In Angular 4+, I've following template driven form:

<form #addForm="ngForm" (ngSubmit)="onFormSubmit($event, addForm)" >
  <div class="form-group">
    <label for="item_name">Item Name</label>
    <input id="item_name" name="item_name" [(ngModel)]="itemName" 
          #item_name="ngModel" autofocus class="form-control"
          required minlength="4" maxlength="20" 
          aria-describedby="itemNameHelpBlock">
    <small *ngIf="(item_name.invalid && item_name.touched)" id="itemNameHelpBlock" class="form-text text-error" >
      Value must be at least 4 characters and must not exceed 20 characters
    </small>
  </div>
  <div class="form-group">
    <label for="item_type">Item Type</label>
    <input id="item_type" name="item_type" [(ngModel)]="itemType" 
         #item_type="ngModel" class="form-control" required minlength="2"
          maxlength="20" aria-describedby="itemTypeHelpBlock">
    <small *ngIf="(item_type.invalid && item_type.touched)" id="itemTypeHelpBlock" class="form-text text-error" >
      Value must be at least 2 characters and must not exceed 20 characters
    </small>
  </div>
  <button class="btn btn-output-primary btn-lg" [disabled]="!addForm.form.valid">Add</button>
</form>

In the component section, I want to access the form field (ie item_name, item_type) as ElementRef so that I can access their corresponding DOM element through the nativeElement method of ElementRef class.

I've tried with @ViewChild but, it returns NgModel class object:

  @ViewChild('item_name') item_name: ElementRef;

  ngAfterViewInit() {
    console.log(this.item_name); // it returns NgModel class object
  }

But, I need to access the DOM HTMLElement of #item_name form field so that I can reset document focus to #item_name input field after every form submission. Now, I don't know how I can do it without directly accessing the DOM and I don't wanna directly access the DOM via DOM api.

I would be glad if I get some help here.

Answer

yurzui picture yurzui · Nov 29, 2017

I would simply add read option to ViewChild query:

@ViewChild('item_name', { read: ElementRef }) item_name: ElementRef;
                           ^^^^^^^^^^^^^^^

Stackblitz Example

See also