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>
