title: How to add/remove a fieldset when click on button
body: <p>I'm programming in Angular2/Typescript and for the add form, I need to add the possibility to add/remove a fieldset in which the input are linked to a ViewModel. So basically, I have a principal ViewModel which comprises a table of the secondary ViewModel (fieldset). I tried different things, but I'm new in Angular so I'm probably missing important things.</p>
  
  <p>Here is the code of my HTML code :</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="form-group"&gt;
                  &lt;div&gt;
                      &lt;label&gt;Customer : &lt;/label&gt;
                      &lt;select class="form-control" required ngControl="viewModel.selectedCustomerStr"
                              [(ngModel)]="viewModel.selectedCustomerStr"&gt;
                          &lt;option value=""&gt;&lt;/option&gt;
                          &lt;option *ngFor="#customer of viewModel.customersListStr" [value]="customer"&gt;{{customer}}&lt;/option&gt;
                      &lt;/select&gt;
                  &lt;/div&gt;
  
                  &lt;div&gt;
                      &lt;label&gt;Service provided: &lt;/label&gt;
                      &lt;select class="form-control" required ngControl="viewModel.serviceProvidedStr"
                              [(ngModel)]="viewModel.serviceProvidedStr"&gt;
                          &lt;option value=null&gt;&lt;/option&gt;
                          &lt;option *ngFor="#service of viewModel.servicesListStr" [value]="service"&gt;{{service}}&lt;/option&gt;
                      &lt;/select&gt;
                  &lt;/div&gt;
  
                  &lt;div&gt;
                      &lt;label&gt;Service window : &lt;/label&gt;
                      &lt;select class="form-control" required ngControl="viewModel.selectedServiceWindowStr"
                          [(ngModel)]="viewModel.selectedServiceWindowStr"&gt;
                          &lt;option value=null&gt;&lt;/option&gt;
                          &lt;option *ngFor="#window of serviceWindowListStr" [value]="window"&gt;{{window}}&lt;/option&gt;
                      &lt;/select&gt;
                  &lt;/div&gt;
  
                  &lt;fieldset *ngFor="#choice of choices"&gt;
                      &lt;legend&gt;DRP contact information&lt;/legend&gt;
                      &lt;div&gt;
                          &lt;label&gt;DRP contact name:&lt;/label&gt;
                          &lt;input placeholder="Contact's Name" type="text" maxlenght=50 [(ngModel)]="viewModel.contactName"
                              class="form-control" required ngControl="name" #name="ngForm"&gt;
                      &lt;/div&gt;
  
                      &lt;div&gt;
                          &lt;label&gt;Start time:&lt;/label&gt;
                          &lt;input class="form-control" ngControl="timeStart" required type="time"
                             [(ngModel)]="viewModel.timeStart"&gt;
                      &lt;/div&gt;
  
                      &lt;div&gt;
                          &lt;label&gt;End time:&lt;/label&gt;
                          &lt;input class="form-control" ngControl="timeEnd" required type="time"
                             [(ngModel)]="viewModel.timeEnd"&gt;
                      &lt;/div&gt;
  
                      &lt;div&gt;
                          &lt;label&gt;Medium:&lt;/label&gt;
                          &lt;select class="form-control" required [(ngModel)]="viewModel.selectedMediumStr" ngControl="viewModel.selectedMediumStr"
                              #medium="ngForm"&gt;
                          &lt;option value=""&gt;&lt;/option&gt;
                          &lt;option *ngFor="#medium of viewModel.mediumsListStr" [value]="medium"&gt;{{medium}}&lt;/option&gt;
                      &lt;/select&gt;
                      &lt;/div&gt;
  
                      &lt;div&gt;
                          &lt;label&gt;DRP contact address:&lt;/label&gt;
                          &lt;input placeholder="Contact's address" type="text" maxlenght=100 [(ngModel)]="viewModel.value"
                              class="form-control" required ngControl="value" #value="ngForm"&gt;
                      &lt;/div&gt;
  
                      &lt;button class="remove" (click)="onRemoveFieldset()"&gt;Remove&lt;/button&gt;
                  &lt;/fieldset&gt;
  
                  &lt;button class="add" (click)="onAddFieldset()"&gt;Add a contact&lt;/button&gt;                  
              &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Do I need to change the ngModel for every input in the fieldset to match the table cell ?</p>
  
  <p>Next is the Typescript code :</p>
  
  <pre class="lang-js prettyprint-override"><code>export class AddDrpsComponent extends BaseComponent implements OnInit {
      viewModel:DrpDetailViewModel = new DrpDetailViewModel();
      tabDrpContact:DrpContactDetailViewModel[];
      serviceWindowListStr:String[];
  
      onAddFieldset() {
          let newItemNo = this.tabDrpContact.length +1;
          this.tabDrpContact.push(new DrpContactDetailViewModel(newItemNo));
      }
  
      onRemoveFieldset(id:number) {
          this.tabDrpContact.splice(id,1);
      }
  }
  </code></pre>
  
  <p>For the moment, it's just a basic add and remove who do nothing behind.</p>
  
  <p><a href="https://i.stack.imgur.com/0ZbtN.png" rel="nofollow noreferrer">Picture of the add form</a></p>
  
  <p>I hope to have been clear, English is not my mother tongue.</p>
  
  <p>Cordially,</p>
  
  <p>Florian</p>
  
  <p>Edit : Up</p>
  
  <p>EDIT 2 : Here is my two ViewModel</p>
  
  <pre class="lang-js prettyprint-override"><code>import {DrpContact} from "./drp-contact";
  
  export interface Drp {
      id:number;
      serviceWindow:string;
      status:string;
      customer:string;
      serviceProvidedType:string;
      drpContactList:DrpContact[];
  }
  </code></pre>
  
  <p>//////////////////////////////////////////////</p>
  
  <pre><code>export interface DrpContact {
      id:number;
      name:string;
      timeStart:string;
      timeEnd:string;
      value:string;
      mediumType:string;
  }
  </code></pre>
  
  <pre class="lang-js prettyprint-override"><code>import {SelectOptionElement} from "../../shared/model/select-option-element";
  import {Serializable} from "../../shared/technical/serializable";
  import {DrpContactDetailViewModel} from "./drp-contact-detail-view-model";
  
  export class DrpDetailViewModel extends Serializable {
      id:number;
  
      selectedCustomer:SelectOptionElement;
      selectedCustomerStr:string;
      serviceProvided:SelectOptionElement;
      serviceProvidedStr:string;
      selectedServiceWindow:SelectOptionElement;
      selectedServiceWindowStr:string;
      status:string;
      drpContactDetailList:DrpContactDetailViewModel[];
  
      customer:SelectOptionElement[];
      customersListStr:String[];
      service:SelectOptionElement[];
      servicesListStr:String[];
      window:SelectOptionElement[];
  }
  
  /////////////////////
  
  
  import {SelectOptionElement} from "../../shared/model/select-option-element";
  import {Serializable} from "../../shared/technical/serializable";
  
  export class DrpContactDetailViewModel extends Serializable {
      id:number;
      contactName:string;
      timeStart:string;
      timeEnd:string;
      selectedMedium:SelectOptionElement;
      selectedMediumStr:string;
      value:string;
  
      medium:SelectOptionElement[];
      mediumsListStr:String[];
  }
  </code></pre>