Búsqueda de sitios web

typescript - Cómo seleccionar solo una casilla de verificación en un formulario dinámico en Angular 8


Tengo un formulario dinámico que está produciendo 8 casillas de verificación diferentes según la respuesta de la API. Ahora quiero que el usuario pueda seleccionar solo 1 casilla de verificación a la vez. Si el usuario quiere seleccionar una casilla diferente, primero tiene que desmarcar la casilla seleccionada. Por favor, consulte el código a continuación.

<ng-container *ngIf="field.inputType==='group';else singleCase">
    <p class="font20" *ngIf="field.label">{{'label.' + field.name | translate}}</p>
    <div class="row purFin table-responsive pb-3 mb-2 mt-4">
      <div class="col-12">
        <ng-container [formArrayName]="field.name"
          *ngFor="let item of group.controls[field.name].controls; let i = index">
          <input type="checkbox" class="hidden" (click)="preventCheck($event)" (change)="onChange($event)" [formControlName]="i"
            [name]="field.name + i+1" [id]="field.name + i+1">
          <label class="btn-outline-secondary mr-3 mt-1 but" [for]="field.name + i+1">
            {{field.options[i].value}}
          </label>
        </ng-container>
        <div class="col-12">
          <span *ngIf="'sub_text.' + field.name | translate"
            class="font12">{{'sub_text.' + field.name | translate}}</span>
        </div>
      </div>
    </div>
    <div *ngIf="group.get(field.name).invalid && (group.get(field.name).dirty || group.get(field.name).touched)"
      class="error-msg">
      <ng-container *ngFor="let validation of field.validations">
        <div *ngIf="group.get(field.name).hasError(validation.name)">{{validation.message}}</div>
      </ng-container>
    </div>
  </ng-container>

Respuesta #1

Se puede hacer de múltiples maneras, reaccionando al evento de cambio/clic y guardando el nombre del elemento marcado/clicado. Considera lo siguiente como un ejemplo, tal vez no sea la solución más elegante, pero en realidad puedes implementar la lógica de muchas formas: [HTML]

export class YourComponentClass  {
  isChecked;
  isCheckedName;
  checkboxData = [1,2,3,4,5,6,7,8];
  onChange(e){       
    this.isChecked = !this.isChecked;
    this.isCheckedName = e.target.name;
  }
}
<div *ngFor="let name of checkboxData">
<input type="checkbox" [name]="name" (change)="onChange($event)" [disabled]="isChecked && (isCheckedName!=name)"> {{'Checkbox ' + name}}
 </div>

en línea: puedes revisarlo en stackblitz

Y en caso de que no necesites mucho de $event, es mejor pasar al componente solo los datos que necesitas, por lo que puedes cambiar a onChange($event.target.name) en el HTML, y en el código TS esto.isCheckedName=e; en consecuencia.

Buena suerte ;)

Respuesta #2

Si estás usando material/cdk en tu aplicación, hay una solución fácil de implementar que involucra SelectionModel y que funciona bien con Reactive Forms/FormBuilder.

En tu componente declara:

selection = new SelectionModel<any>(false, []);

Luego, en tu plantilla/html:

  <tr *ngFor="let item of formArray['controls']; let i = index;" [formGroupName]="i" class="tr-body-format">
        <td class="td-format">
             <mat-checkbox formControlName="selected" (change)="$event ? 
                  selection.toggle(i) : null" [checked]="selection.isSelected(i)">
             </mat-checkbox>
         </td>