How to make make single checkbox select from mat-selection-list. Similar to radio button which accepts one value from group of values.
From a philosophical and UX perspective, you need to use radio buttons. This is the only way to provide user-friendly "as expected" behavior.
you can declare the [selected]
attribute of mat-list-option
for example:
<mat-selection-list #list>
<mat-list-option *ngFor="let item of myList"
[(mgModel)]="selectedOption"
[selected]="item.id === selectedOption.id"
[value]="item">
{{item.name}}
</mat-list-option>
</mat-selection-list>
by this way you reach just one selection without changing any MatSelectionList hidden property.
Also you can do it by replacing ngModel
with controller logic,
by this way you will save the last selection object in class variable.
<mat-list-option (selectionChange)="onChange($event)"`
see also Binding an Angular Material Selection List
Try this: I've got it working with a tick, changing css
:host ::ng-deep .mat-radio-outer-circle{
border-radius:2px;
}
:host ::ng-deep .mat-radio-inner-circle{
border-radius:2px;
background-color: transparent!important;
border-bottom: 4px solid white;
border-right:4px solid white;
height:30px;
width:15px;
margin-top: -8px;
margin-left: 3px;
}
:host ::ng-deep .mat-radio-checked .mat-radio-outer-circle{
background:#ff4081!important;
}
:host ::ng-deep .mat-radio-checked .mat-radio-inner-circle{
transform: rotate(45deg) scale(0.5);
}
:host ::ng-deep .mat-radio-button .mat-radio-ripple{
height: 20px; /*double of your required circle radius*/
width: 20px; /*double of your required circle radius*/
left: calc(50% - 10px); /*'10px'-same as your required circle radius*/
top: calc(50% - 10px); /*'10px'-same as your required circle radius */
}
What you need is probably a <mat-radio-group>
rather than a <mat-selection-list>
, Its a list of options but only one option can be selected. an example can be found at the Angular Material docs.
But be advised that instead of a checkbox you'll get a radio button.
Just set the multiple option of MatSelectionList to false:
ngOnInit() {
this.links.selectedOptions._multiple = false;
}
and you're done. Also by doing this you will be able to deselect the selected checkbox.
To begin with, mat-selection-list
is not suitable for a single-value selection, as it veers away from its intent:
Checkboxes in a group are non-exclusive options; more than one checkbox in a group can be checked at any given time
What you're looking for is the radio-button element itself, because semantically it stands for:
A radio button is one of a group of controls representing mutually-exclusive choices
Unfortunately Angular Material does not include a mat-radio-list
component. But you can still achieve it by including a mat-radio-button
inside you mat-list-item
. This will provide best practice, as it denotes to the user that the list in view is intended for mutually-exclusive choices (unlike checkboxes that denote multiple-choice). And since the radio buttons are updating a single variable, you get exclusivity:
<mat-list role="list">
<mat-list-item role="listitem" *ngFor="let x of [0,1,2]; let i = index">
<mat-radio-button [value]="i" (change)="selection = $event.value">
Item {{x}}
</mat-radio-button>
</mat-list-item>
</mat-list>
Check a Stackblitz