Binding an Angular Material Selection List

TDC picture TDC · Nov 17, 2017 · Viewed 62.3k times · Source

I am creating a Toolbar with a selection list (checkboxes with each list item) using Angular Material 2. I just cannot figure out how to set the checkboxes before the list is displayed and then get the selected items following user interaction.

I am trying the control within a Form thinking I may need this to bind to ngModel, but this doesn't seem to help. My html so far is:

<form
  novalidate
  #areaSelectForm="ngForm">

<div>
    <mat-selection-list 
                        #areasList="ngModel"
                        [(ngModel)]="model"
                        id="areaListControl"
                        name="areaListControl"
                        (ngModelChange)="onAreaListControlChanged($event)">
        <mat-list-option *ngFor="let tta of taskTypeAreas" (click)="onCheckboxClick($event)" [value]="tta">
            {{tta}}
        </mat-list-option>
    </mat-selection-list>
</div>

</form>

This must be a well trodden path but the documentation is difficult to interpret and I cannot seem to find any suitable examples.

Any guidance very welcome please.

Answer

LLai picture LLai · Nov 17, 2017

As of version 5.0.0, angular material now supports ngModel for selection list.

So the code can be simplified to

<mat-selection-list #list [(ngModel)]="selectedOptions" (ngModelChange)="onNgModelChange($event)">
    <mat-list-option *ngFor="let tta of taskTypeAreas" [value]="tta.name">
        {{tta.name}}
    </mat-list-option>
</mat-selection-list>

The release also exposes an ngModelChange event for selection list. Here is the updated stack blitz


(Original answer before Angular 5.0.0)

It appears mat-selection-list does not currently support ngModel (https://github.com/angular/material2/pull/7456), but it looks like it will be supported in the near future. In the meantime you can use a reference variable #list to grab the selected options.

// component.html
<mat-selection-list #list>
    <mat-list-option *ngFor="let tta of taskTypeAreas" [selected]="tta.selected" 
        (click)="onAreaListControlChanged(list)" [value]="tta.name">
        {{tta.name}}
    </mat-list-option>
</mat-selection-list>

Then pass in the reference variable to your onAreaListControlChanged(list) method so you can parse out the selected options.

// component.ts
onAreaListControlChanged(list){
    this.selectedOptions = list.selectedOptions.selected.map(item => item.value);
}

To select the checkboxes on load, you can use the [selected] property of each <mat-list-option>.

<mat-list-option ... [selected]="tta.selected" ...>

To do this you'll need to add another property to your array.

// component.ts
taskTypeAreas: {
    name: string;
    selected: boolean;
}[] = [
    {
        name: 'Area 1',
        selected: false
    },
    {
        name: 'Area 2',
        selected: false
    },
    {
        name: 'Area 3',
        selected: true
    },
];

This will make Area 3 be selected on load. Here is a stackblitz demoing this.