8

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>
0

1 Answer 1

18

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)
Sign up to request clarification or add additional context in comments.

11 Comments

Ok, thanks, but the main problem is to access this.form.valid (child component) from the parent component. The @viewchild from the parent is what i am most interested about @ViewChild(RightPanelComponent) rightPanelPointer: RightPanelComponent;
This will work rightPanelPointer.form.valid in the parent component
I have got: a property form doesn't exist on type RightPanelComponent , i do not know if it is because my form is a template-driven form placed into the html.
did you add @ViewChild(NgForm) form; to RightPanelComponent ?
what if you have multiple instances of RightPanelComponent?
|

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.