3

I have a submit button in parent component. Also I have several child components. Now I want to enable the button to save all values of the form in all child components once the validation passed. In parent component, I created the form group.

 public mainForm: FormGroup; 

In constructor of the parent component,

 constructor(private fb: FormBuilder) { this.mainForm = this.fb.group({ child1Form: this.fb.group({ projectName: [null, Validators.required], projectSource: [null, Validators.required] }); }); } 

In the parent html, we pass the form to the child.

<div> <app-child1 [child1Form]="mainForm.controls['child1Form']"></app-child1> </div> 

In child component html, the code is:

<form [formGroup]="child1Form"> <div> <input [(ngModel)]="projectName" formControlName="projectName"> </div> <div> <input [(ngModel)]="projectSource" formControlName="projectSource"> </div> </form> 

In the ts file of the child component, we use the form from the parent component.

 @Input() child1Form: any; 

What I want is in the ngOnInit of the parent component, check the form validation.

ngOnInit() { this.mainForm.statusChanges.subscribe(data => { const f = this.mainForm.controls['child1Form']; if(f.valid || f.dirth) // do something such as enable/disable the submit button }); } 

However my question is the code didn't reach statusChanges part even I changed the text in the input control of the child component. I assume that when I type something the form's value or status is changed so I can do the validation.

5
  • 1
    On your child component try <input formControlName="projectName"> and <input formControlName="projectSource"> Commented Sep 25, 2019 at 3:18
  • 1
    @HuiZhao, you needn't subscribe to status change to enabled a button, just in .html `<button [enabled]="this.mainForm.get('child1Form').valid">submit</button>. But take account Joao say: use formControlName in child Commented Sep 25, 2019 at 6:35
  • @Eliseo, I have several child forms, child1 is just an example for demo. Commented Sep 25, 2019 at 9:22
  • My bad, I forgot to add formControlName in the demo, just updated it. I have it in my real code. Commented Sep 25, 2019 at 9:39
  • [enabled]="this.mainForm.valid">submit</button> for whole form Commented Sep 25, 2019 at 13:27

1 Answer 1

9

Let's solve this problem step by step:

  1. Create a parent & child component
  2. Add the following HTML template in parent.component.html
<form> <app-child></app-child> <button>Submit</button> </form> 
  1. Add the following HTML template in child.component.html
<form [formGroup]="child1Form"> <div> <input type="text" formControlName="projectName" required> </div> <div> <input type="text" formControlName="projectSource" required> </div> </form> 
  1. Create a formGroup for child1Form in child.component.ts (I've declared the 'child1Form' in the 'child.component.ts' not in the 'parent.component.ts')
 child1Form: FormGroup; constructor(private fb: FormBuilder) { } ngOnInit() { this.child1Form = this.fb.group({ projectName: ['', Validators.required], projectSource: ['', Validators.required] }) } 
  1. Now, subscribe to statusChanges & emit the value in the child.component.ts
 @Output() isChild1FormValid: EventEmitter<boolean> = new EventEmitter<boolean>(); ngOnInit() { this.child1Form.statusChanges.subscribe(value => { if(value === 'VALID') { this.isChild1FormValid.emit(true); } }); } 
  1. Listen for the emitted value in the parent.component.html
<form> <app-child (isChild1FormValid)="enableSubmitButton($event)"></app-child> </form> 
  1. Hold the value in a property inside parent.component.ts
 isChild1FormValid: boolean; enableSubmitButton(isValid: boolean) { this.isChild1FormValid = isValid; } 
  1. Enable the submit button if the isChild1FormValid property is true (parent.component.html)
<form> <button type="submit" [disabled]="!isChild1FormValid">Submit</button> </form> 
  1. Full working demo in StackBlitz
Sign up to request clarification or add additional context in comments.

8 Comments

Sakib, it's unnecesary "output" the isChild1FormValid. a formGroup is valid is all its formGroup and formControls are valid. You can check in the main.component. Really it is unnecesary too subscribe to statusChanged, each time you change an input, Angular know if the form is valid or not
If I have several child components, should I use a long condition such as [disabled]="!isChild1FormValid ||!isChild2FormValid || !isChild3FormValid || .... "
use && instead of | |
I saw in your parent component there is aform tag(Step 6). But you don't have it in the StackBlitz.
Strange! I'm seeing a form tag. Here is the parent component code <form> <app-child (isChild1FormValid)="enableSubmitButton($event)"></app-child> <button type="submit" [disabled]="!isChild1FormValid">Submit</button> </form>
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.