首页 > 解决方案 > One checkbox select is also triggering other checkbox

问题描述

I have some data that i am showing using ngFor directive in a table. I have checkbox in the last column and i want it to select only the row that will be selected but not the other rows. Here is my code

HTML Code

<div *ngIf="!admin">
          <div class="row clearfix">
            <div class="col-sm-12">
              <input type="checkbox" name="permission12" value="" (change)="isSelected = !isSelected" class="filled-in" id="permission12" (click)="chosen(listSupportAdminSchools.items)" />
              <label for="permission12">: Select All</label>
              <table class="table-bordered table-striped" style="width:100%">
                <thead>
                  <tr>
                    <th>Name</th>
                    <th>Registration Number</th>
                    <th>Enrollment Type</th>
                    <th>Entity Type</th>
                    <th>Location</th>
                    <th>IsActive</th>
                    <th>Select</th>
                  </tr>
                </thead>
                <tbody>
                  <tr *ngFor="let x of listSupportAdminSchools.items;">
                    <td>{{x.name}}</td>
                    <td>{{x.registrationNumber}}</td>
                    <td>{{x.educationType}}</td>
                    <td>{{x.administrativeType}}</td>
                    <td>{{x.county}}
                      <span>,</span>{{x.city}}
                      <span>,</span>{{x.district}}</td>
                    <td></td>
                    <td style="text-align: center">
               <!--       <button (click)="onClick()" class="btn btn-primary waves-effect">Select</button>   -->
                      <input type="checkbox" name="permission13" value="" [(ngModel)] = "isSelected" class="validate form-control" id="permission13" (click)="chosen()" />
                      <label for="permission13">: Select</label>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>

while in my .ts file i have a isSelected boolean variable set to false.

Whenever i click on one checkbox in the row it select other one too. But the select all checkbox is working just fine

标签: htmlangulartypescript

解决方案


This issue is not caused by angular, but rather by how HTML handles the label's for attribute. The browser looks for the first element with a matching id property and sends all clicks there.

To fix this, you need to give each checkbox a unique id:

<div *ngIf="!admin">
  <div class="row clearfix">
    <div class="col-sm-12">
      <input type="checkbox" name="permission12" value="" (change)="isSelected = !isSelected" class="filled-in" id="permission12" (click)="chosen(listSupportAdminSchools.items)" />
      <label for="permission12">: Select All</label>
      <table class="table-bordered table-striped" style="width:100%">
        <thead>
          <tr>
            <th>Name</th>
            <th>Registration Number</th>
            <th>Enrollment Type</th>
            <th>Entity Type</th>
            <th>Location</th>
            <th>IsActive</th>
            <th>Select</th>
          </tr>
        </thead>
        <tbody>
          <tr *ngFor="let x of listSupportAdminSchools.items; let i = index">
            <td>{{x.name}}</td>
            <td>{{x.registrationNumber}}</td>
            <td>{{x.educationType}}</td>
            <td>{{x.administrativeType}}</td>
            <td>{{x.county}}
              <span>,</span>{{x.city}}
              <span>,</span>{{x.district}}</td>
            <td></td>
            <td style="text-align: center">
       <!--       <button (click)="onClick()" class="btn btn-primary waves-effect">Select</button>   -->
              <input type="checkbox" [name]="'permission13' + 1" value="" [(ngModel)] = "x.isSelected" class="validate form-control" [id]="'permission13' + i" />
              <label [for]="'permission13' + i">: Select</label>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</div>

Changes:

First, we use modify the *ngFor to track the index for us

*ngFor="let x of listSupportAdminSchools.items; let i = index"

Then, we do some simple string concatination to ensure each checkbox id is unique

[id]="'permission13' + i"

Finally, we modify the label for in the same way

[for]="'permission13' + i"

Notes:

  • By adding the [] brackets around the attribute, we make angular process this as Javascript. This lets us use the + operator.
  • Since it is now Javascript we need to add '' around permission13 so it is treated as a string, rather than a variable name
  • This is the simplest way to accomplish this, you could also generate these value from other unique properties of your *ngFor object, eg [id]="'permission13' + x.objectId"

(OBSELETE) Update for single row selected:

Update checkbox binding:

[ngModel] = "selectedRow === x" (ngModelChange)="selectedRow = x"

You will need a property in the model selectedRow. When a checkbox is clicked, it sets this value. Each checkbox is now bound to an expression, so only one checkbox should appear checked at a time.


推荐阅读