0

I’m implementing a multi-select dropdown using Angular Material’s <mat-select multiple> and cdk-virtual-scroll-viewport for performance with large datasets.

Problem:
When I select multiple branches, scroll down, and then select more branches, the earlier selected ones become unselected.

<mat-select multiple [(ngModel)]="selectedBranches" [compareWith]="compareBranches">
  <mat-select-trigger>
    <span *ngIf="selectedBranches.length === 0">Select branches...</span>
    <span *ngIf="selectedBranches.length === 1">{{ selectedBranches[0].name }}</span>
    <span *ngIf="selectedBranches.length > 1">{{ selectedBranches.length }} branches selected</span>
  </mat-select-trigger>

  <!-- Search input -->
  <div class="search-container">
    <mat-form-field appearance="outline" class="search-field">
      <mat-label>Search branches</mat-label>
      <input matInput [(ngModel)]="searchText" (ngModelChange)="onSearchChange()" />
      <mat-icon matSuffix>search</mat-icon>
    </mat-form-field>
  </div>

  <!-- Select All -->
  <div style="margin-left: 17px; margin-bottom: 8px; margin-top: 8px;">
    <mat-checkbox
      [checked]="selectAllChecked"
      [indeterminate]="isIndeterminate()"
      (change)="toggleSelectAll($event)"
    >
      Select All
    </mat-checkbox>
  </div>

  <!-- Virtual scroll -->
  <cdk-virtual-scroll-viewport itemSize="48" class="branch-viewport">
    <mat-option
      *cdkVirtualFor="let branch of branchDropdownList; trackBy: trackByBranchId"
      [value]="branch"
    >
      {{ branch.code }} - {{ branch.name }}
    </mat-option>
  </cdk-virtual-scroll-viewport>
</mat-select>

What I’ve Tried:

  • Implemented [compareWith] comparing branch.id to preserve selection.

  • Verified branchDropdownList contains unique objects.

  • Added trackBy with *cdkVirtualFor.

  • Ensured branchDropdownList array isn’t being reassigned unnecessarily.

  • Tested without virtual scroll — selection works fine.

Expected Behavior:
Selections should persist regardless of scrolling or loading more options.

Actual Behavior:
With virtual scroll enabled, earlier selections disappear when scrolling and selecting new items.

What I’ve Tried Implemented [compareWith] function comparing branch.id to preserve selection.

Environment:

  • Angular 13.x

  • @angular/material 13.x

  • @angular/cdk 13.x

  • Tailwind CSS 3.x

How can I persist selected items in a Material multi-select that uses cdk-virtual-scroll-viewport, so selections are not lost after scrolling? Is there a recommended way to use [compareWith] or trackBy to prevent DOM recycling from breaking selection state?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.