lpd
lpd

Reputation: 417

How to validate multiple forms in a single component ?(Reactive Forms Validation)

<div class="modal-body">
<ul class="nav nav-pills" role="tablist">
    <li class="nav-item"><a class="nav-link active" data-toggle="pill" href="#EmployerLogin">Employer</a></li>
    <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#seekerLogin">Candidate</a></li>
</ul>
<div class="tab-content">
    <div id="EmployerLogin" class="tab-pane  active">
        <form class="form-horizontal" [formGroup]="registerForm" (ngSubmit)="employerLogin()">
            <input type="email" [(ngModel)]="emplogin.employer_email" formControlName="elogin" name="empname" class="form-control"
                [ngClass]="{ 'is-invalid': submitted && f.elogin.errors }" placeholder="Email">
            <div *ngIf="submitted && f.elogin.errors" class="invalid-feedback">
                <div *ngIf="f.elogin.errors.required"> Email is required</div>
            </div>
            <button class="btn btn-default">Login</button>
        </form>
    </div>
    <div id="seekerLogin" class="tab-pane fade">
        <form class="form-horizontal" [formGroup]="registerForm" (ngSubmit)="seekerLogin()">
            <input type="text" [(ngModel)]="seekerlogin.seeker_email" formControlName="empEmail" name="empname"
                class="form-control" [ngClass]="{ 'is-invalid': submitted && f.empEmail.errors }" placeholder="Email">
            <div *ngIf="submitted && f.empEmail.errors" class="invalid-feedback">
                <div *ngIf="f.empEmail.errors.required"> Email is required</div>
            </div>
            <button class="btn btn-default">Login</button>
        </form>
    </div>
</div>

login.ts

 import { Component, OnInit } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    @Component({
        selector: 'my-Header',
        templateUrl: './header.component.html',
    })
    export class HeaderComponent implements OnInit {
        constructor(private formBuilder: FormBuilder) { }
        registerForm: FormGroup;
        ngOnInit() {
            this.registerForm = this.formBuilder.group({
                elogin: ['', Validators.required]
            });
        }
        submitted: Boolean = false;
        // Employer  Login Method
       get f() { return this.registerForm.controls; }

        employerLogin() {
            this.submitted = true;
            if (this.registerForm.invalid) {
                return;
            }
        }
        // Seeker  Login Method
        seekerLogin() {
            this.submitted = true;
            if (this.registerForm.invalid) {
                return;
            }
        }
    }

How to validate both forms ,when i am trying to validate one of them its showing error for both side.is there any other way to validate multiple forms in a single component using Angular 6.Please note I am very new to Angular 6 and typescript, so I might be missing something obvious. :)

Upvotes: 1

Views: 7659

Answers (2)

sumit
sumit

Reputation: 289

You can create a form structure like this:

MasterForm = this.formbuilder.group({
grp1 = new FormGroup({
   formControl1,
   formControl2
}),
grp2 = new FormGroup({
   formControl3,
   formControl2
})
}, { validator: matchEmailsDomain(formControl1,formControl3)});

Create this form in some service. And now in your component get form object using some method of service like this:

getFormObject(){
   return this.MasterForm;
}

In your component then you can do something like this:

ngOnInit(){
   this.myUserForm = this.myFormService.getFormObject();
}

and in html use this myUserForm as [formGroup]="myUserForm ";

In your validator

export function matchEmailsDomain(fc1, fc2): ValidatorFn {
    return (control: FormGroup): ValidationErrors | null => {

       // your validator logic here

    };
}

Upvotes: 1

SiddAjmera
SiddAjmera

Reputation: 39482

Since you're using the submitted boolean property to check for both the forms and each has a field that has a Validators.required applied to them, it won't be possible with just one FormGroup.

You will have to either create two different FormGroups altogether or you'll have to create two different FormGroups in the same registerForm FormGroup.

I'm going to show the latter approach in this answer:

Here's your Component:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(private formBuilder: FormBuilder) { }
  registerForm: FormGroup;
  ngOnInit() {
    this.registerForm = this.formBuilder.group({
      employerGroup: this.formBuilder.group({
        elogin: ['', Validators.required]
      }),
      candidateGroup: this.formBuilder.group({
        empEmail: ['', Validators.required]
      })
    });
  }
  employerSubmitted: boolean = false;
  candidateSubmitted: boolean = false;
  // Employer  Login Method
  get fe() { return (<FormGroup>this.registerForm.get('employerGroup')).controls; }

  get fc() { return (<FormGroup>this.registerForm.get('candidateGroup')).controls; }

  get employerGroup() {
    return this.registerForm.get('employerGroup');
  }

  get candidateGroup() {
    return this.registerForm.get('candidateGroup');
  }

  employerLogin() {
    this.employerSubmitted = true;
    if (this.registerForm.invalid) {
      return;
    }
  }
  // Seeker  Login Method
  seekerLogin() {
    this.candidateSubmitted = true;
    if (this.registerForm.invalid) {
      return;
    }
  }

}

And then in your Component Template, bind to these FormGroups:

<div class="modal-body">
    <ul class="nav nav-pills" role="tablist">
        <li class="nav-item"><a class="nav-link active" data-toggle="pill" href="#EmployerLogin">Employer</a></li>
        <li class="nav-item"><a class="nav-link" data-toggle="pill" href="#seekerLogin">Candidate</a></li>
    </ul>
    <div class="tab-content">
        <div id="EmployerLogin" class="tab-pane  active">
            <form class="form-horizontal" [formGroup]="employerGroup" (ngSubmit)="employerLogin()">
                <input type="email" formControlName="elogin" name="empname" class="form-control"
                [ngClass]="{ 'is-invalid': employerSubmitted && fe.elogin.errors }" placeholder="Email">
            <div *ngIf="employerSubmitted && fe.elogin.errors" class="invalid-feedback">
                <div *ngIf="fe.elogin.errors.required"> Email is required</div>
            </div>
            <button class="btn btn-default">Login</button>
        </form>
    </div>

    <br>

    <div id="seekerLogin" class="tab-pane fade">
        <form class="form-horizontal" [formGroup]="candidateGroup" (ngSubmit)="seekerLogin()">
            <input type="text" formControlName="empEmail" name="empname"
                class="form-control" [ngClass]="{ 'is-invalid': candidateSubmitted && fc.empEmail.errors }" placeholder="Email">
            <div *ngIf="candidateSubmitted && fc.empEmail.errors" class="invalid-feedback">
                <div *ngIf="fc.empEmail.errors.required"> Email is required</div>
            </div>
            <button class="btn btn-default">Login</button>
        </form>
    </div>
</div>

Here's a Working Sample StackBlitz for your ref.

Upvotes: 4

Related Questions