jrdnmdhl jrdnmdhl - 2 months ago 56
TypeScript Question

Dynamically adding/removing controls to Angular2 form

I have an angular2-final form with a variable number of checkbox inputs using the *ngFor directive. This seems to work fine, as long as the number of checkboxes is set once in ngOnInit. However, I need to be able to add/remove checkboxes dynamically and I'm not sure how to do that.

What component logic is necessary to make it so that the inputs can be added/removed from a model-driven form, like the one below, on the fly?

Example form code:

<form [formGroup]="editProjectForm" (ngSubmit)="edit()" *ngIf="!isLoading">
<div class="form-group">
<label class="hero-form-label" for="name">Name</label>
<input class="form-control" type="text" name="name" formControlName="name">
</div>
<div class="form-group">
<label class="hero-form-label" for="description">Description</label>
<input class="form-control" type="text" name="description" formControlName="description">
</div>

<label class="hero-form-label">Members</label>
<table class="table table-bordered table-striped">
<thead class="thead-default">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email Address</th>
<th>Include</th>
</tr>
</thead>
<tbody *ngIf="project?.members === 0">
<tr>
<td colspan="4">This project has no members.</td>
</tr>
</tbody>
<tbody>
<tr *ngFor="let user of users">
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.email}}</td>
<td>
<input type="checkbox" name="{{user.id}}" value="{{user.id}}" value="{{ project.hasUser(user.id) }}">
</td>
</tr>
</tbody>
</table>

Answer

Looking at your template I'm not sure where you are adding a variable number of checkboxes, unless you are referring to your users loop.

To answer your exact question:

What component logic is necessary to make it so that the inputs can be added/removed from a model-driven form?

What you'll need is the FormArray class. It can contain a variable number of controls, which should be able to solve your use case. You can use an *ngFor with a FormArray.

Your model driven form could look something like this:

editProjectForm = new FormGroup({
  name: new FormControl(''),
  description: new FormControl(''),
  users: new FormArray([
    new FormGroup({
      firstName: new FormControl(''),
      lastName: new FormControl(''),
      email: new FormControl(''),
      options: new FormArray([
        new FormGroup({
          type: new FormControl('Project Has User'),
          value: new FormControl(false)
        })
      ])
    })
  ])
});

And Angular2 bind array with ngFor has an example of binding to FormArray.

Comments