Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a form is valid from a parent component using Angular 4

I am trying to check the validity of a form placed on a child component from a parent component. The best scenario would be to disable a button on the parent component if the form is invalid or in the worse scenario to trigger an alert from the parent button if form is invalid.

I could achieve to check if the form has 'ng-invalid' class from the parent using a @ViewChild decorator to call a function on the child component as follows:

Parent Component:

export class CandidateVerificationComponent implements OnChanges, OnInit {

@ViewChild(RightPanelComponent) rightPanelPointer: RightPanelComponent;

saveAndFinish() {

    if (this.rightPanelPointer.checkFormValidity())
    {
        alert('No Valid');
        return;
    }

    this.rightPanelPointer.onSubmit();

  }    
}

Child Component:

export class RightPanelComponent implements OnChanges , OnInit{

@ViewChild("candiateForm", { read: ElementRef }) tref: ElementRef;

   checkFormValidity():boolean {        
    return (this.tref.nativeElement.className.indexOf('ng-invalid') !== -1);
   }  
}

It works for the worst scenario, but I do not like the idea to link the component to the DOM, I would rather a smarter idea.

I would like to use a template reference variable (#candiateForm), for example the one that allows to check validity in the submit button (see below) from the form (child) in order to check validity from the parent. Is it possible to have access to that template variable from the parent?

 <form (ngSubmit)="onSubmit()" #candiateForm="ngForm" name="candiateForm" (change)="formChanged()">
    <div class="form-group">
      <label class="control-label" for="firstName">First name:</label>                           
      <input type="text" class="form-control" id="firstName" pattern="^[^0-9]+$" required [(ngModel)]='candidate.firstName' name="firstName" #firstName="ngModel">
   </div>
<button type="submit" class="btn btn-default" [disabled]="!candiateForm.form.valid">Submit</button>
</form>
like image 978
D.B Avatar asked Jul 06 '17 08:07

D.B


1 Answers

Since Angular applies ngForm to all form elements implicitly and you can reference any component/directive in the component template by component/directive class reference, you don't have to read ElementRef and don't need the template reference #candiateForm, you can access the form directly by the directive class reference ngForm:

export class RightPanelComponent implements OnChanges , OnInit{
    @ViewChild(NgForm) form;

    checkFormValidity():boolean {        
        return this.form.valid;
    }

And also you can access the form directly from the parent component:

export class CandidateVerificationComponent implements OnChanges, OnInit {
    @ViewChild(RightPanelComponent) rightPanelPointer: RightPanelComponent;

    saveAndFinish() {
        if (this.rightPanelPointer.form.valid)
like image 188
Max Koretskyi Avatar answered Sep 20 '22 05:09

Max Koretskyi