Jean
Jean

Reputation: 621

Angular 6: retrieve elements of a ngFor list with checkboxes

I d like to display an array using ngFor on Angular (I m working with Angular 6). I want to be able to select some of my car by clicking on a checkbox At the end, when I press the button, I will buy the selected cars.

The list display alrigh, so do the checkboxes, but I dont really know how to easily retrieve the selected cars . Can you help? I've tried some of the examples I've found on StackoverFlow with no success

I don't want to touch the car model which only contains 3 fields (id brand and price)

<thead>
<button type="button" click="buySelectedCars()">BUY</button>
</tr>
<th>car id</th>
<th>car brand</th>
<th>car price</th>
<th> checkbox</th>
<tr>
</thead>
<tbody>
<tr *ngFor="let car of cars">
<td>{{car.id}}</td>
<td>{{car.brand}}</td>
<td>{{car.price}}</td>
<td>
<input type="checkbox" [checked]='car.check'></td>
</td>
</tr>
</tbody>

TS:

buySelectedCars(){
    for (car of cars){
    if car.check{
    this.carService.buyCar(car);
    }
    }
}

Upvotes: 0

Views: 1618

Answers (3)

Amit Anand
Amit Anand

Reputation: 305

To retrieve the values of the user selected checkboxes. You first need to uniquely identify each checkbox. One way to do this is to set the value attribute of the input tag to car.id . From here we can extract the value of the checkbox from its event. So for every change call a method and pass the event.

Inside the typescript first check if the checkbox is checked or unchecked if it is checked push the value in the userSelect list. Similarly, for those cases where user unchecked some values then we need to iterate through the list to remove that entry

Here is the modified code for your case:

HTML

<thead>
<button type="button" click="buySelectedCars()">BUY</button>
</tr>
<th>car id</th>
<th>car brand</th>
<th>car price</th>
<th> checkbox</th>
<tr>
</thead>
<tbody>
<tr *ngFor="let car of cars; let i = index">
<td>{{car.id}}</td>
<td>{{car.brand}}</td>
<td>{{car.price}}</td>
<td>
<input type="checkbox" value = "{{ car.id }}" (change) = "getUserSelect($event,i)"></td>
</td>
</tr>
</tbody>

TS

userSelect = [];
getUserSelect(ev, index) {
    if(ev.target.checked == true) {
        this.userSelect.push(ev.target.value);
    }
    else {
        // removing any entry if user unchecked any previously selected value
        for(let i = 0;i < userSelect.length; i++) {
            if(userSelect[i] == ev.target.value) {
                this.userSelect.splice(i,1);
            }
        }
    }
 }

Upvotes: 1

Jose Luis Berrocal
Jose Luis Berrocal

Reputation: 155

The easiest way is by using Reactive forms, with Angular material mat-selection-list so for example

<mat-selection-list formControlName="cars">
  <mat-checkbox *ngFor="let car of cars" labelPosition="after"
              [value]="car.id">
  </mat-checkbox>
</mat-selection-list>

then on TS you can extract the data by using

this.form.get('cars').value

Upvotes: 1

De Wet van As
De Wet van As

Reputation: 1000

You could maintain an array of checked items.

for example:

html:

<td>
<input type="checkbox" [checked]='cars.indexOf(car) > -1' (change)="checkChanged(car)"></td>
</td>

ts:

//declare array

const cars = [];

//function
checkChanged(car)
{
  const checkedCar = this.cars.find(c => c.id === car.id);
  if(checkedCar)
  {
    this.cars.splice(this.cars.indexOf(checkedCar), 1);
  }
  else
  {
    this.cars.push(car);
  }
}

Upvotes: 1

Related Questions