1

Inside the parent component I have a child component. Both have their required fields. At the end I need the enable the submit button only if both components are valid (all their required fields are filled in this case).

How can I accomplish this, especially with template-driven validation?

Seed code

parent component

@Component({ selector: 'parent-comp', templateUrl: 'parent.html' }) export class Parent { } <input pInputText name="txt1" id="txt1" required/> <child-comp></child-comp> <button pButton type="button" label="Submit" [disabled]="IF ONE OF THE COMPS IS NOT VALID"></button> 

child component

@Component({ selector: 'child-comp', templateUrl: 'child.html' }) export class Child { } <input pInputText name="txt2" id="txt2" required/> 

2 Answers 2

7

For validating both parent and child component, a single form need to be divided into multiple component.

Parent html

<form #parentForm="ngForm"> <input pInputText name="txt1" id="txt1" required/> <child-comp></child-comp> <button pButton type="button" label="Submit" [disabled]="!parentForm.valid"></button> </form> 

Parent Component

 import { Component } from '@angular/core'; @Component({ selector: 'parent-comp', templateUrl: 'parent.html' }) export class Parent { } 

Child Form must not have form tag

<input pInputText name="txt2" id="txt2" required/> 

Child Component

import { Component } from '@angular/core'; import { ControlContainer, NgForm } from '@angular/forms'; @Component({ selector: 'child-comp', templateUrl: 'child.html', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }) export class Child { } 
Sign up to request clarification or add additional context in comments.

1 Comment

This worked for me. Only had to import the ControlContainer and NgForm, and add the viewProviders. Quick and simple.
2

You can create @Output variable in child that will emit form.valid value. You need to use FormBuilder and FormGroup (don't see it here).

Every time you change something inside form, you need to call a function that will emit onchange.

Example for child:

@Output onchange: EventEmitter<Boolean> = new EventEmitter(false); formInChild: FormGroup; constructor(private fb: FormBuilder) { this.formInChild = fb.group(...) this.formInChild.valueChanges.subscribe(() => { this.onchange.emit(this.form.valid); } } 

Now in parent:

(view)

<child-comp (onchange)="setButtonState($event)"></child-comp> <button pButton type="button" label="Submit" [disabled]="!allvalid"></button> 

(component)

formInParent: FormGroup; allvalid: boolean = false; constructor(private fb: FormBuilder) { this.formInParent = fb.group(...); } setButtonState(formFromChildValid) { this.allvalid = this.formInParent.valid && formFromChildValid; } 

In this case every time you change something in child's form, child's form valid state will be emitted to parent which will update allvalid variable which is listened by button.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.