FabianRinortner
FabianRinortner

Reputation: 103

How can I receive the values from a form in the parent component?

I have a template with two components in it. Both components are forms and will be filed in the template.

Now I want to receive the values from the forms in the parent component and check if the forms are valid. Then I want to enable the button to submit the value of both forms.

The template looks like this:

<section>
  <app-first-form></app-first-form>
  <app-second-form></app-second-form>

  <button [disabled]="first-form.invalid || second-form.invalid"> submit</button>
</section>

The tstemplate from one of the forms:

<form [formGroup]="form" (ngSubmit)="submitForm()">
  <mat-form-field>
    <mat-label>Vorname</mat-label>
    <input
      matInput
      formControlName="name"
      name="name">
  </mat-form-field>
  <button
    type="submit"
    [disabled]="form.invalid">submit Form
  </button>
</form>

The ts file from one of the forms:

export class OneOfTheForms implements OnInit {

  form: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.form = this.fb.group({
      name: [null, Validators.required],
    });
  }
}

Would be great if someone could show me how to do this. Thanks!

Upvotes: 0

Views: 945

Answers (2)

Eliseo
Eliseo

Reputation: 57919

another aproach using template reference variables (it's the same that use viewChild but only using html). Remember that by defect all the variables of a components are public. If you use a template reference variable you can "get" all the variables

<section>
  <app-first-form #first></app-first-form>
  <app-second-form #second></app-second-form>

  <button [disabled]="first.form.invalid || second.form.invalid"> submit</button>
</section>
<pre>
{{first.form?.value}}
{{second.form?.value}}
</pre>

Upvotes: 0

KShewengger
KShewengger

Reputation: 8269

You can achieve that with @Output() on both elements or @ViewChild() handling everything inside the ParentComponent. I would suggest to use @ViewChild and handle the 2 forms there.

Have created a Stackblitz Demo for your reference.

ParentComponent

@Component({...})
export class ParentComponent {

  @ViewChild(Form1Component) form1: Form1Component;
  @ViewChild(Form2Component) form2: Form2Component;
  
  body: any;

  constructor() {}

  // Check if both forms are valid after validating that this.form1 and this.form2 already exists
  get isFormValid(): boolean {
    if (this.form1 && this.form2) return this.form1.form.valid && this.form2.form.valid;
  }

  save(): void {
    const { value: form1Values } = this.form1.form;       // Get form1 form values
    const { value: form2Values } = this.form2.form;       // Get form2 form values

    // If both forms are valid, assign and merge result inside the body
    if (this.isFormValid) this.body = {...form1Values, ...form2Values};
  }

}

Both the Form1 and Form2 Components don't have any Submit buttons, we only have 1 submit button and it's on the ParentComponent which checks their form status and fetches their form values.

Upvotes: 1

Related Questions