Saturday, October 16, 2021

Compare validator using reactive forms in angular

 Comparing two input values using reactive forms in angular






Step 1 : Validation.ts


import { AbstractControl, ValidatorFn } from '@angular/forms';

export default class Validation {
  static match(controlName: string, checkControlName: string): ValidatorFn {
    return (controls: AbstractControl) => {
      const control = controls.get(controlName);
      const checkControl = controls.get(checkControlName);

      if (checkControl?.errors && !checkControl.errors.matching) {
        return null;
      }

      if (control?.value !== checkControl?.value) {
        controls.get(checkControlName)?.setErrors({ matching: true });
        return { matching: true };
      } else {
        return null;
      }
    };
  }
}

Step 2 : app-component.html

<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
      <form (ngSubmit)="onSubmit()" [formGroup]="form" autocomplete="off">
        <div id="user-data" formGroupName="userData">
          <div class="form-group">
            <label for="username" class="text-warning">User Name</label>
            <input type="username" placeholder="User Name" name="username" formControlName="username"
              class="form-control" />
            <span class="text-danger"
              *ngIf="!(form.get('userData.username')?.valid) && form.get('userData.username')?.touched">Please enter
              user name</span>
          </div>
          <div class="form-group">
            <label for="email" class="text-warning">Email</label>
            <input type="text" placeholder="Email" name="email" class="form-control" formControlName="email" />
            <span class="text-danger"
              *ngIf="!(form.get('userData.email')?.valid) && form.get('userData.email')?.touched">Please enter valid
              email</span>
          </div>
        </div>
        <div class="form-group">
          <label for="password" class="text-warning">Password</label>
          <input type="password" class="form-control" name="password" formControlName="password"
            [ngClass]="{ 'is-invalid':  f.password.errors }"
            placeholder="Password" />
          <span class="text-danger" *ngIf="f.password.errors?.required && f.password.touched">Please enter
            password</span>
          <span class="text-danger" *ngIf="f.password.errors?.minlength && f.password.touched">Password must be 6
            characters
          </span>
        </div>
        <div class="form-group">
          <label for="confirmpassword" class="text-warning">Confirm Password</label>
          <input type="password" class="form-control" name="confirmpassword" formControlName="confirmpassword"
            [ngClass]="{ 'is-invalid':  f.confirmpassword.errors }"
            placeholder="Confirm Password" />
          <span class="text-danger" *ngIf="f.confirmpassword.errors?.required && f.confirmpassword.touched">Please enter
            confirm password</span>
          <span class="text-danger" *ngIf="f.confirmpassword.errors?.matching && f.confirmpassword.touched">Confirm
            Password does not match</span>
        </div>

        <h4 *ngIf="hobbies.length < 2; else t" class="text-warning">Your Hobby</h4>
        <ng-template #t>
          <h4 class="text-warning">Your Hobbies</h4>
        </ng-template>

        <div class="form-group" formArrayName="hobbies">
          <button type="button" class="btn btn-success" (click)="onAddingHobby()">Add Hobby</button>
          <div id="dynamicControls" class="form-group" *ngFor="let l of hobbies.controls; let i = index">
            <span class="col-xs-5">
              <input type="text" [placeholder]="'Hobby ' + (i + 1)" [formControlName]="i" class="form-control"></span>
            <span><button id="removeControl" type="button" class="btn btn-danger" (click)="onRemovingHobby(i)">X
              </button></span>
          </div>
        </div>
        <button type="submit" [disabled]="!this.form.valid" class="btn btn-primary">Submit</button>
      </form>
    </div>
  </div>
</div>


Step 3 : app-component.ts

import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import Validation from './utils/validation';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  excludedUserName: string[] = ['Test', 'test'];
  form!: FormGroup;

  constructor(private formBuilder: FormBuilder) { }
 
  ngOnInit(): void {
    this.form = this.formBuilder.group({
      'userData': new FormGroup({
        'email': new FormControl(null, [Validators.required, Validators.email]),
        'username': new FormControl(null, [Validators.required,
        this.excludedUserNames.bind(this)])
      }),
      'password': new FormControl(null, [Validators.required, Validators.minLength(6)]),
      'confirmpassword': new FormControl(null, Validators.required),
      'hobbies': new FormArray([])
    }, {
      validators: [Validation.match('password', 'confirmpassword')]
    });
  }

  onSubmit() {
    console.log(this.form);
  }

  onAddingHobby() {
    const control = new FormControl(null, Validators.required);
    this.hobbies.push(control);
  }
  onRemovingHobby(i: number) {
    this.hobbies.removeAt(i);
  }

  excludedUserNames(fromControl: FormControl): { [s: string]: boolean } | null {
    if (this.excludedUserName.indexOf(fromControl.value) !== -1) {
      return { 'excludedUserName': true };
    }
    return null;
  }

  get hobbies() {
    return this.form.get('hobbies') as FormArray;
  }
 
  get f(): { [key: string]: AbstractControl } {
    return this.form.controls;
  }
}

No comments:

Post a Comment