user1704842
user1704842

Reputation: 35

Angular2 Dynamically duplicate input fields

In this tutorial under the "Dynamically Duplicate Input Elements" Module, In the video #3. She demonstrates how to hide controls with a checkbox. When she clicks on "Send Catalog" is when the Address appears. That's how she hides and shows the address block. She has the [(ngModel)] outside the formarray hence its doing the hide and show toggle thing correctly. The problem I have is that I have to do the toggle affect inside the address block. Lets say when I check the "Work" radio button it only have to display City and State, but when I click the Home it should give me full address. I am trying to achieve some similar affect as the above example I have stated.

The problem I get with it is when I use the [(ngModel)] and *ngif to get the hide/show affect inside the FormArray. When I choose a an option in the DDL It is duplicating exact same thing in all the following blocks of the formgroup. I am not sure how to fix this. Did any of you had the similar problem and were able to fix it? Do you know how I can do the Hide/Show toggle affect without using ([ngModel])?? I have attached an image if you want to see what I was talking about. Thanks in advance!!

component.html

 <div formArrayName="Disciplines" *ngFor="let discipline of Disciplines.controls; let i=index">
                <div [formGroupName]="i">
                    <div class="form-group">
                        <label class="col-md-2 control-label">Discipline</label>
                        <div class="col-md-3">
                            <label class="control-label" id="fireId" name="agencyProfile-label-fireId" attr.for="{{fireId + i}}">
                                <input id="{{fireId + i}}" name="Fire"
                                       type="checkbox" formControlName="Fire">
                                Fire
                            </label>
                        </div>
                        <div class="col-md-3">
                            <label class="control-label" id="medicalId" name="agencyProfile-label-medicalId" attr.for="{{medicalId + i}}">
                                <input id="{{medicalId + i}}" name="Medical"
                                       type="checkbox" formControlName="Medical">
                                Medical
                            </label>
                        </div>
                        <div class="col-md-3">
                            <label class="control-label" id="policeId" name="agencyProfile-label-policeId" attr.for="{{policeId + i}}">
                                <input id="{{policeId + i}}" name="Police"
                                       type="checkbox" formControlName="Police">
                                Police
                            </label>
                        </div>
                    </div>

                    <!--<div *ngIf="agency.Fire || agency.Medical || agency.Police">-->
                        <div class="form-group">
                            <div class="col-md-12">
                                <label class="col-md-2 control-label" id="contractTermsId" name="agencyProfile-label-contractTermsId" attr.for="{{contractTermsId + i}}">Contract Terms</label>
                                <div class="col-md-6">
                                    <select class="form-control" id="{{contractTermsId + i}}" name="agencyProfile-drodown-contractTermsId" formControlName="ContractTermId" [(ngModel)]="agency.ContractTerms">
                                        <option *ngFor="let d of contract" [value]="d.ContractTermId">{{d.ContractTerms}}</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                        <div *ngIf="agency.ContractTerms == 1">
                            <div class="form-group">
                                <div class="col-md-12">
                                    <label class="col-md-2 control-label" attr.for="{{FirstEndDateId + i}}" id="FirstEndDateId" name="agencyProfile-label-FirstEndDate">First EndDate<span class="compulsary">*</span></label><br>
                                    <div class="col-md-4">
                                        <input type="date" id="{{FirstEndDateId + i}}" formControlName="FirstEndDate" />
                                        <!--<my-date-picker id="renewalDateTextId" name="agencyProfile-datepicker-renewalDateTextId" [options]="myDatePickerOptions"
                            formControlName="RenewalDate"></my-date-picker>-->
                                    </div>
                                    <label class="col-md-1 control-label" attr.for="{{secondEndDateId + i}}" id="secondEndDateId" name="agencyProfile-label-secondEndDateId">Second EndDate<span class="compulsary">*</span></label><br>
                                    <div class="col-md-4">
                                        <input type="date" id="{{secondEndDateId + i}}" formControlName="SecondEndDate" />
                                        <!--<my-date-picker id="renewalDateTextId" name="agencyProfile-datepicker-renewalDateTextId" [options]="myDatePickerOptions"
                            formControlName="RenewalDate"></my-date-picker>-->
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div *ngIf="agency.ContractTerms == 2">
                            <div class="form-group">
                                <div class="col-md-12">
                                    <label class="col-md-2 control-label" attr.for="{{startDateId + i}}" id="startDateId" name="agencyProfile-label-startDateId">Start Date<span class="compulsary">*</span></label><br>
                                    <div class="col-md-4">
                                        <input type="date" id="{{startDateId + i}}" formControlName="StartDate" />
                                        <!--<my-date-picker id="renewalDateTextId" name="agencyProfile-datepicker-renewalDateTextId" [options]="myDatePickerOptions"
                            formControlName="RenewalDate"></my-date-picker>-->
                                    </div>
                                    <label class="col-md-1 control-label" attr.for="{{endDateId + i}}" id="endDateId" name="agencyProfile-label-endDateId">End Date<span class="compulsary">*</span></label><br>
                                    <div class="col-md-4">
                                        <input type="date" id="{{endDateId + i}}" formControlName="EndDate" />
                                        <!--<my-date-picker id="renewalDateTextId" name="agencyProfile-datepicker-renewalDateTextId" [options]="myDatePickerOptions"
                            formControlName="RenewalDate"></my-date-picker>-->
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-12">
                                <label class="col-md-2 control-label" attr.for="{{renewalDateId + i}}" id="renewalDateId" name="agencyProfile-label-renewalDateId">Renewal Date<span class="compulsary">*</span></label><br>
                                <div class="col-md-2">
                                    <input type="date" id="{{renewalDateId + i}}" formControlName="RenewalDate" />
                                    <!--<my-date-picker id="renewalDateTextId" name="agencyProfile-datepicker-renewalDateTextId" [options]="myDatePickerOptions"
                        formControlName="RenewalDate"></my-date-picker>-->
                                </div>
                                <label class="col-md-1 control-label" attr.for="{{followupDateId + i}}">FollowUp Date<span class="compulsary">*</span></label><br>
                                <div class="col-md-2 ">
                                    <input type="date" id="{{followupDateId + i}}" formControlName="FollowupDate" />
                                    <!--<my-date-picker name="followupDate" [options]="myDatePickerOptions"
                        formControlName="FollowupDate"></my-date-picker>-->
                                </div>
                                <label class="col-md-1 control-label" attr.for="{{checklistDateSentId + i}}">CheckList Date Sent</label><br>
                                <div class="col-md-2">
                                    <input type="date" id="{{checklistDateSentId + i}}" formControlName="CheckListDateSent" />
                                    <!--<my-date-picker name="primerDate" [options]="myDatePickerOptions"
                        formControlName="PrimerDate"></my-date-picker>-->
                                </div>
                            </div>
                        </div>
                    <!--</div>-->
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-2">
                    <button class="col-md-12 btn btn-primary"
                            name="agencyProfileTab-button-searchUserProfileId"
                            (click)="addDisciplines()"
                            type="button">
                        Add Discipline
                    </button>
                </div>
            </div>

component.ts

import { Component, OnInit, AfterViewInit, OnDestroy, ViewChildren, ElementRef} from '@angular/core';
import { FormBuilder, FormGroup, FormControl, FormArray, Validators, FormControlName } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';

import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/merge';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { IAgencyStatus } from './iagencystatus';
@Component({
    moduleId: module.id,
    templateUrl: 'agencyprofile.component.html'
})

export class AgencyProfileComponent implements OnInit, AfterViewInit, OnDestroy {
    @ViewChildren(FormControlName, { read: ElementRef }) formInputElements: ElementRef[];

        agency: IAgencyProfile;

    get Disciplines(): FormArray {
            return <FormArray>this.agencyForm.get('Disciplines');
        }
     ngOnInit(): void {
            this.Form = this.fb.group({
                Disciplines: this.fb.array([this.buildDisciplines()]),
    }

     addDisciplines(): void {
            this.Disciplines.push(this.buildDisciplines());
        }
     buildDisciplines(): FormGroup {
            return this.fb.group({
                ContractTerms: '',
                ContractTermId: 0,
                StartDate: null,
                EndDate: null,
                FirstEndDate: null,
                SecondEndDate: null,
                Fire: false,
                Medical: false,
                Police: false,
                FollowupDate: null,
                RenewalDate: null,
                CheckListDateSent: null
            });
        }

Picture for the above html form In the above image I have select Fire for the 1st block and clicked "Add Discipline". The same selection has been done to the next block automatically! Let me know if you have any more questions

Upvotes: 2

Views: 3147

Answers (1)

DeborahK
DeborahK

Reputation: 60518

When using reactive forms, this line:

formControlName="Medical"

is binding this input element to the control in the Form model. Since all of the copies of this input element have the same formControlName they are all updating when you update one.

Try modifying the formControlName using the same technique you use for your id property:

formControlName={{Medical+ i}}

So they each have a unique name.

Let me know if that works for you.

Upvotes: 2

Related Questions