2

I have created a signup form in ionic4 with fields like first name, last name, email, password and confirm password.

I have added validations also like showing the fields are required if user left or touch the respective fields.

I wanted to add validations for password and confirm password. i.e if the password and confirm password mismatching error.

below is my code:

html file:

<ion-content>

  <div style="margin: 30px">
    <ion-title class="ion-text-center">Register</ion-title>

    <form [formGroup]="loginForm">
      <ion-item>
        <ion-label position="floating">First Name*</ion-label>
        <ion-input formControlName="fname" type="text"></ion-input>
      </ion-item>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.fname">
          <div class="error-message" *ngIf="loginForm.get('fname').hasError(error.type) && (loginForm.get('fname').dirty || loginForm.get('fname').touched)">
            {{ error.message }}
          </div>
        </ng-container>

      </div>
      <ion-item>
        <ion-label position="floating">Last Name*</ion-label>
        <ion-input formControlName="lname" type="text"></ion-input>
      </ion-item>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.lname">
          <div class="error-message" *ngIf="loginForm.get('lname').hasError(error.type) && (loginForm.get('lname').dirty || loginForm.get('lname').touched)">
            {{ error.message }}
          </div>
        </ng-container>

      </div>
      <ion-item>
        <ion-label position="floating">Email Id*</ion-label>
        <ion-input formControlName="email" type="text"></ion-input>
      </ion-item>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.email">
          <div class="error-message" *ngIf="loginForm.get('email').hasError(error.type) && 
        (loginForm.get('email').dirty || loginForm.get('email').touched)">
            {{ error.message }}
          </div>
        </ng-container>

      </div>

      <ion-item>
        <ion-label position="floating">Password*</ion-label>
        <ion-input formControlName="password" type="password"></ion-input>
      </ion-item>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.password">
          <div class="error-message" *ngIf="loginForm.get('password').hasError(error.type) && (loginForm.get('password').dirty || loginForm.get('password').touched)">
            {{ error.message }}
          </div>
        </ng-container>

      </div>
      <ion-item>
        <ion-label position="floating">Confirm Password*</ion-label>
        <ion-input formControlName="confirmpassword" type="password"></ion-input>
      </ion-item>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.confirmpassword">
          <div class="error-message" *ngIf="loginForm.get('confirmpassword').hasError(error.type) && (loginForm.get('confirmpassword').dirty || loginForm.get('confirmpassword').touched)">
            {{ error.message }}
          </div>
        </ng-container>

      </div>
      <br>
      <div>
        <ion-button [disabled]="!loginForm.valid" expand="full">Signup</ion-button>
      </div>

    </form>

  </div>

</ion-content>

.ts file:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {

  loginForm: FormGroup;

  error_messages = {
    'fname': [{
      type: 'required',
      message: 'First Name is required.'
    }, ],

    'lname': [{
      type: 'required',
      message: 'Last Name is required.'
    }],

    'email': [{
        type: 'required',
        message: 'Email is required.'
      },
      {
        type: 'minlength',
        message: 'Email length.'
      },
      {
        type: 'maxlength',
        message: 'Email length.'
      },
      {
        type: 'required',
        message: 'please enter a valid email address.'
      }
    ],

    'password': [{
        type: 'required',
        message: 'password is required.'
      },
      {
        type: 'minlength',
        message: 'password length.'
      },
      {
        type: 'maxlength',
        message: 'password length.'
      }
    ],
    'confirmpassword': [{
        type: 'required',
        message: 'password is required.'
      },
      {
        type: 'minlength',
        message: 'password length.'
      },
      {
        type: 'maxlength',
        message: 'password length.'
      }
    ],
  }

  constructor(
    public formBuilder: FormBuilder
  ) {
    this.loginForm = this.formBuilder.group({
      fname: new FormControl('', Validators.compose([
        Validators.required
      ])),
      lname: new FormControl('', Validators.compose([
        Validators.required
      ])),
      email: new FormControl('', Validators.compose([
        Validators.required,
        Validators.minLength(6),
        Validators.maxLength(30)
      ])),
      password: new FormControl('', Validators.compose([
        Validators.required,
        Validators.minLength(6),
        Validators.maxLength(30)
      ])),
      confirmpassword: new FormControl('', Validators.compose([
        Validators.required,
        Validators.minLength(6),
        Validators.maxLength(30)
      ])),
    })
  }

  ngOnInit() {}

}

Please help me how can I add validations for password and confirm password if entered are mismatching.

1 Answer 1

4

Just create a validator that accepts a FormGroup and returns an error if both these fields don't match.

import { Component } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';

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

  error_messages = { ... }

  constructor(
    public formBuilder: FormBuilder
  ) {
    this.loginForm = this.formBuilder.group({
      fname: new FormControl('', Validators.compose([
        Validators.required
      ])),
      ...
      confirmpassword: new FormControl('', Validators.compose([
        Validators.required,
        Validators.minLength(6),
        Validators.maxLength(30)
      ])),
    }, { 
      validators: this.password.bind(this)
    });
  }

  ngOnInit() {
  }

  password(formGroup: FormGroup) {
    const { value: password } = formGroup.get('password');
    const { value: confirmPassword } = formGroup.get('confirmpassword');
    return password === confirmPassword ? null : { passwordNotMatch: true };
  }

}

UPDATE:

And in your Template:

<div class="container">

  <div style="margin: 30px">
    <h1 class="ion-text-center">Register</h1>

    <form [formGroup]="loginForm">
      <div class="form-group">
        <label>First Name*</label>
        <input class="form-control" formControlName="fname" type="text" />
      </div>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.fname">
          <div class="error-message" *ngIf="loginForm.get('fname').hasError(error.type) && (loginForm.get('fname').dirty || loginForm.get('fname').touched)">
            {{ error.message }}
          </div>
        </ng-container>
      </div>

      ...

      <div class="form-group">
        <label>Confirm Password*</label>
        <input class="form-control" formControlName="confirmpassword" type="password" />
      </div>
      <div class="error-messages">
        <ng-container *ngFor="let error of error_messages.confirmpassword">
          <div class="error-message" *ngIf="loginForm.get('confirmpassword').hasError(error.type) && (loginForm.get('confirmpassword').dirty || loginForm.get('confirmpassword').touched)">
            {{ error.message }}
          </div>
        </ng-container>
        <div class="error-message" *ngIf="!loginForm.get('confirmpassword').errors && loginForm.hasError('passwordNotMatch') && (loginForm.get('confirmpassword').dirty || loginForm.get('confirmpassword').touched)">
          Password and Confirm Password fields should match
        </div>
      </div>

      <button class="form-control btn btn-primary" [disabled]="!loginForm.valid">Signup</button>
    </form>
  </div>
</div>

Here's a Working Sample StackBlitz for your ref.

Sign up to request clarification or add additional context in comments.

6 Comments

@ SiddAjmera ,Thank you soo much for your answer, but in the stackblitz example you have given its displaying 'Form Error - null' in the form itself and getting error messgs after entering the password. i want to display password mismatching error only after entering the password fields. please help me on this
@Saif, I've updated the answer and the sample stackblitz. Please check if that helps.
thank you soo much @SiddAjmeera, it perfectly works now
hi @SiddAjmeera, Sorry for disturbing you again. If i want to add two more fields with require confim validations like Mobile no. and Confirm mobile no. how can i add to the existing code. I tried creating one more form group for mobile but its not working. please help me on this thank you.
I'd suggest you ask a separate question for that just so that we can keep this thread focused. BTW, you should be able to do that using the same approach that was demonstrated in the answer. In the custom validator that we've created, just add validation for a contact number and confirm contact number too. If you are still struggling, plese go ahead and ask a separate quesiton.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.