1

I'm trying to make a form with multiple components. I tried doing this using template driven form. Here is the code I'm having problems with:

<form #f="ngForm" (ngSubmit)="onSubmit(f)">
      <app-employee></app-employee>
      <hr>
      <app-experiences-and-education></app-experiences-and-education>
      <input type="submit" value="Submit" class="btn btn-primary btn block">
    </form>

Here is the employee component:

    <div class="form-group">
  <label for="name"> Name </label>
  <input  type="text" name="name" [(ngModel)]="employee.name" #employeeName="ngModel" id="Name" minlength="3" required class="form-control">
  <div class="alert alert-danger mt-2" *ngIf="employeeName.errors?.required && employeeName.touched">
    Name Is Required
  </div>
  <div class="alert alert-danger mt-2" *ngIf="employeeName.errors?.minlength && employeeName.touched">
    Name at least 3 haracters
  </div>
</div>

<div class="form-group">
  <label for="address"> Address </label>
  <input type="text" name="address" [(ngModel)]="employee.address" #employeeAddress="ngModel" minlength="3" required class="form-control">
  <div class="alert alert-danger mt-2" *ngIf="employeeAddress.errors?.required && employeeAddress.touched">
    Address Is Required
  </div>
  <div class="alert alert-danger mt-2" *ngIf="employeeAddress.errors?.minlength && employeeAddress.touched">
    Address at least 3 haracters
  </div>
</div>

<div class="form-group">
  <label for=""> Gender:  </label>
  <label for="male">
    Male
    <input type="radio" name="gender" value="m" id="male" [(ngModel)]="employee.gender">
  </label>

  <label for="female">
      Female
      <input type="radio" name="gender" value="f" id="female">
    </label>

  <!-- <input type="text" name="gender" [(ngModel)]="employee.gender" #employeeGender="ngModel" id="gender" required class="form-control"> -->
  <div class="alert alert-danger mt-2" *ngIf="employeeGender.errors?.required && employeeGender.touched">
    Gender Is Required
  </div>
</div>

Here is the experience and education component:

    <div class="form-group">
  <label for="experiance"> Experiance </label>
  <textarea name="experiance" id="" cols="30" rows="5" [(ngModel)]="employee.experiance" #employeeExperiance="ngModel" id="Experiance" minlength="3"
  required class="form-control"></textarea>

  <div class="alert alert-danger mt-2" *ngIf="employeeExperiance.errors?.required && employeeExperiance.touched">
    Last Name Is Required
  </div>
  <div class="alert alert-danger mt-2" *ngIf="employeeExperiance.errors?.minlength && employeeExperiance.touched">
    Experiance at least 3 haracters
  </div>
</div>

<div class="form-group">
    <label for="education"> Education </label>
    <textarea name="education" id="" cols="30" rows="5" [(ngModel)]="employee.education" #employeeEducation="ngModel" id="education" minlength="3"
    required class="form-control"></textarea>

    <div class="alert alert-danger mt-2" *ngIf="employeeEducation.errors?.required && employeeEducation.touched">
      Last Name Is Required
    </div>
    <div class="alert alert-danger mt-2" *ngIf="employeeEducation.errors?.minlength && employeeEducation.touched">
      Education at least 3 haracters
    </div>
  </div>

Here is the method parents component:

onSubmit(submitForm: NgForm) {
    console.log(submitForm.value);
   }

I got only this error screen shot: enter image description here

1
  • Hey dude, can you explain me why are you using two-data binding way : [(ngModel)] ? In this case normally simple directive ngModel is enought isn't ? Commented May 18, 2018 at 18:26

2 Answers 2

6

The method to divide an Angular form into multiple components is pretty straight forward.

First of all create the main component that contains the form:-

import { Component } from '@angular/core';

@Component({
    selector: 'main-form',
    template: `
        <div class="container">
            <form #mainForm="ngForm">
                <div class="form-group">
                    <label for="name">Name</label>
                    <input type="text" class="form-control" id="name"
                           required
                           [(ngModel)]="name" name="name">
                </div>
                <child-form-component></child-form-component>
            </form>
            <pre>{{ mainForm.value | json }}</pre>
        </div>
    `
})
export class MainComponent {
    name: string = "";
}

Then create the child component :-

import { Component } from '@angular/core';
import { ControlContainer, NgForm } from '@angular/forms';

@Component({
    selector: 'child-form-component',
    template: `
        <fieldset ngModelGroup="childDetails">
            <div class="form-group">
                <label for="child-name">Child Name</label>
                <input class="form-control" id="child-name" type="text" name="childName" [(ngModel)]="childName">
            </div>
        </fieldset>
    `,
    viewProviders: [{ provide: ControlContainer, useExisting: NgForm }]
})
export class ChildFormComponent {
    childName: string = "";
}

Notice the line "viewProviders: [{ provide: ControlContainer, useExisting: NgForm }]" in the child component, that's the only thing new in this code, but you don't have to worry that much about it just use it as it is in your code. For more elaborated explanation follow this link.

Also notice how "mainForm.value" is used in the main component.

Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant! This addresses EXACTLY what I needed to know.
0

The error is because of the commented out line. Uncomment it.

<!-- <input type="text" name="gender" [(ngModel)]="employee.gender" #employeeGender="ngModel" id="gender" required class="form-control"> -->

3 Comments

i fixed the error but it still this function consoling an empty object onSubmit(submitForm: NgForm) { console.log(submitForm.value); }
you cant access the values from different component in this manner.
so how can i make this form with 2 components how can i solve it

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.