Search code examples
angularionic4angular-forms

Angular 9 Template driven form validition and setFocus to next field doesn't work together


I have template driven login form on angular 9

 <form name="login" #loginForm="ngForm" (ngSubmit)="loginForm.form.valid && login()" *ngIf="loginPage"  novalidate>
      <ion-item>
        <ion-label position="stacked">{{accountPage.your_email}} </ion-label>
        <ion-input type="email" (keyup)="gotoNextField($event, password2)" [(ngModel)]="creds.email" name="email" #email="ngModel" [ngClass]="{ 'is-invalid': loginForm.submitted && email.invalid }" required="ngModel" email autofocus="true"></ion-input>
        <ion-item *ngIf="email.invalid && (email.dirty || email.touched)">
            <ion-text color="danger">
              <p>{{accountPage.check_email}}</p>
            </ion-text>
        </ion-item>
      </ion-item>
      <ion-item>
        <ion-label position="stacked"><span style="float:left; margin-top:7px;">{{accountPage.your_password}}</span> <ion-button fill="clear" size="small" style="float:right" (click)="forgotPassword()">{{accountPage.forget_password}}</ion-button></ion-label>
        <ion-input type="password" (keyup)="initLogin($event, loginForm.form.valid)"  [(ngModel)]="creds.password" name="password2"  #password2="ngModel" minlength="8" required="ngModel"></ion-input>
        <ion-item *ngIf="password2.invalid && (password2.dirty || password2.touched)">
          <ion-text color="danger">
            <p>{{accountPage.password_desc}}</p>
          </ion-text>
        </ion-item>
      </ion-item>
      <ion-button  class="cv-btn-primary" size="large" expand="full" type="submit" [disabled]="loginForm.invalid"  ><ion-icon name="mail-outline"></ion-icon> &nbsp;{{accountPage.login}} {{accountPage.with_password}}</ion-button>
 </form>

I have this code in ts file to set focus to next field if user press "return" or enter key on keyboard.

public gotoNextField(event, nextElement){
    if(event.keyCode === 13){
      nextElement.setFocus();
    }
  }

This code works sets focus to the next field only if #email is present like this in ion-input.

<ion-input type="email" (keyup)="gotoNextField($event, password2)" [(ngModel)]="creds.email" name="email" #email [ngClass]="{ 'is-invalid': loginForm.submitted && email.invalid }" required="ngModel" email autofocus="true"></ion-input>

The failure validation text shows in the UI only if #email="ngModel"

<ion-input type="email" (keyup)="gotoNextField($event, password2)" [(ngModel)]="creds.email" name="email" #email="ngModel" [ngClass]="{ 'is-invalid': loginForm.submitted && email.invalid }" required="ngModel" email autofocus="true"></ion-input>

The validation & set focus to the next field doesn't work together. Am I missing something? (or) is there any workaround to make it both work together?


Solution

  • Since you have assigned password2 template varaible to ngModel it's pointing to ngModel instance, we can use Viewchild decorator in component to get TextInput reference.

    First import TextInput from ionic angular module. Then use read property on ViewChild to get ion-input reference in component.

    component.ts

      import { TextInput } from 'ionic-angular';
    
      @ViewChild('password2', {read:TextInput}) textInput:TextInput;
       
      public gotoNextField(event, nextElement){
        if(event.keyCode === 13){
          this.textInput.setFocus();
        }
      }