Search code examples
angularcomponentsangular2-forms

Include a component as FormControl Angular2


I have component that has form built through form builder and now in that form i need to include a component that has only one input box as a form control.

add.ts

this.newForm = this.fb.group({
      name: ['', [Validators.required]],
      surname:['', [Validators.required]],
      time: ''
    });

"time" has to be included as a different component.

add.html

<div class="form-group">
            <label class="col-md-3 control-label" for="name">{{'forms.newForm.label.configuration.name' | translate}}</label>  
            <div class="col-md-3">
              <input type="text" formControlName="name" placeholder="placeholder" 
                  class="form-control input-md" type="text">
              <small *ngIf="!newForm.controls.name.valid && newForm.controls.name.dirty" class="text-danger">
                Name is required.
              </small>
            </div>

            <label class="col-md-3 control-label" for="surname">{{'forms.newForm.label.configuration.name' | translate}}</label>  
            <div class="col-md-3">
              <input type="text" formControlName="surname" placeholder="placeholder" 
                  class="form-control input-md" type="text">
              <small *ngIf="!newForm.controls.surname.valid && newForm.controls.name.dirty" class="text-danger">
                Surname is required.
              </small>
            </div>
          </div>

time.html

<div>
  <div class="col-md-7">
    <input class="form-control input-md" type="text" (keydown)="eventHandler($event)" maxlength="11">
    <small *ngIf="!validTime" class="text-danger">
      Invalid time
    </small>
  </div>
</div>

How to i include form control "time" as a component in the main form so i can access the value through this.newForm.controls['time'].value??


Solution

  • A single FormControl cannot be passed separately to the child component in that way, you need to bind it with [formControl] to be able to do that, create a custom form control or pass it within a formgroup to the child. Here it will be easiest to bind the control with [formControl] in the child:

    this.newForm = this.fb.group({
        name: ['', [Validators.required]],
        surname:['', [Validators.required]],
        time: ['']
    });
    

    In your parent html pass the time formcontrol to your child:

    <time-comp [time]="newForm.get('time')"></time-comp>
    

    and child template:

    <input [formControl]="time">
    

    And do not forget to mark the form control received from parent with Input:

    @Input() time: FormControl;
    

    Then you can access the time value (in your parent) with:

    this.newForm.get('time').value;
    

    Also notice that you do not need any events, like keyup, the changes will be catched by the parent without them.