1
votes

I am new to Angular and I am making a Reactive Form.

I have a *ngIf directive on an 'em' tag that validates whether the Input text value is valid, if not valid the 'em' tag is supposed to be injected into the HTML and shows "Required"

<em *ngIf="!validateLastName()">Required</em>

How can I get this *ngIf to fire each time I move my mouse away from the Input control?

Here is the whole div:

<div class="form-group" [ngClass]="{'error' :!validateLastName()}">
          <label for="lastName">Last Name:</label>
          <em *ngIf="!validateLastName()">Required</em>
          <input formConrolName="lastName" id="lastName" type="text" 
          class="form-control" placeholder="Last Name..." />
        </div>

Here is the validation code in the component:

validateLastName(){ 
   return this.lastName.valid || this.lastName.untouched 
}

I am taking an Angular course on Pluralsight (Angular Fundamentals by Jim Cooper and Joe Eames) and the course author is able to have his "validateLastName() method on the em tag fire when he navigates away from the control. I don't see where they have any other settings or code that causes the validation to happen, it just seems to happen automatically when they navigate away from the Input.

Any ideas?

Here is the whole HTML code for this component (profile.component.html):

<div>
    <h1>Edit Your Profile </h1>
    <hr>
    <div class="col-md-4">
      <form [formGroup]="profileForm" (ngSubmit)="saveProfile(profileForm.value)" 
      autocomplete="off" novalidate>
        <div class="form-group" [ngClass]="{'error' : !validateFirstName() }">
          <label for="firstName">First Name:</label>
          <em *ngIf="!validateFirstName()">Required</em>
          <input fromControlName="firstName" id="firstName" (blur)="validateLastName()" type="text" 
          class="form-control" placeholder="First Name..." />
        </div>
        <div class="form-group" [ngClass]="{'error' :!validateLastName()}">
          <label for="lastName">Last Name:</label>
          <em *ngIf="!validateLastName()">Required</em>
          <input formConrolName="lastName" id="lastName" type="text" 
          class="form-control" placeholder="Last Name..." />
        </div>

        <button type="submit" class="btn btn-primary">Save</button>
        <button type="button" (click)="cancel" class="btn btn-default">Cancel</button>
      </form>
    </div>
  </div>

Here is the component (profile.component.ts):

import { Component, OnInit } from '@angular/core'
import { FormControl, FormGroup, Validators } from '@angular/forms'; 
import { AuthService } from './auth.service'
import { Router } from "@angular/router"

@Component({
templateUrl: "./profile.component.html",
styles: [`
    em {float-right; color:#E05C65; padding-left: 10px;}
    .error input {background-color:#E3C3C5;}
    .error ::-webkit-input-placeholder { color: #999; }
    .error ::-moz-placeholder { color: #999 }
    .error :-moz-placeholder { color: #999 }
    .error :ms-input-placeholder { color: #999 }
 `]
})
export class ProfileComponent implements OnInit {
  profileForm:FormGroup
  private firstName:FormControl
  private lastName:FormControl 
  constructor(private auth:AuthService, private router:Router){ 
  }

  ngOnInit(){  
     this.firstName = new FormControl(
      this.auth.currentUser.firstName, Validators.required) 

    this.lastName = new FormControl(
      this.auth.currentUser.lastName, Validators.required) 

      this.profileForm = new FormGroup({
      firstName: this.firstName,
      lastName: this.lastName

    })  
  }

  saveProfile(formValues){
    console.log("Form is valid: " + this.profileForm.valid)
    if (this.profileForm.valid){
      this.auth.updateCurrentUser(formValues.firstName.value,             
       formValues.lastName.value)
      this.router.navigate(["events"])
    } 
  }

  validateFirstName(){ 
    console.log("Is Valid: " + (this.firstName.valid ||         
    this.firstName.untouched))
    return this.firstName.valid || this.firstName.untouched 
  }

  validateLastName(){ 
    return this.lastName.valid || this.lastName.untouched 
  }

  cancel(){
    this.router.navigate(["events"])
  }
}
3
Try using es6 getter- get validateFirstName(){......} and In HTML *ngIf="validateFirstName"Chellappan வ

3 Answers

2
votes

There are proper methods to handle your case, here is the runnable demo:

two-way binding

<em *ngIf="!isLastNameValid()">Required</em>
   <br />
   <input type="text" [(ngModel)]="value"/>

  value = "Cattie";
  isLastNameValid() {
    return this.value === "Cattie";
  }

listen blur event

   <em *ngIf="!isValid">Required</em>
   <br />
   <input type="text" #myInput (blur)="validateName(myInput.value)"/>

  isValid = false;
  validateName(value: string) {
    this.isValid = value === "Cattie";
  }
1
votes

This can help: the "mouseleave" event

<input formConrolName="lastName" id="lastName" type="text" 
          class="form-control" (mouseleave)="validateLastName()" placeholder="Last Name..." />

Edit: depending upon your Angular version, you may want to try:

(mouseout)="validateLastName()"
0
votes

You can simply use form methods rather than calling a component method like this.

<em *ngIf="profileForm.get('firstName').invalid && profileForm.get('firstName').dirty">Required</em>

There are multiple flags for each control such as valid, invalid, pristine, touched etc.,. you can play around with the flags directly in HTML template rather than calling a component method to validate your fields.