Currently, I am attempting to build a basic select list using the Angular Material List Module.
However, I am encountering an issue when trying to integrate this with a filter. While I have managed to implement this functionality, I face difficulty in filtering and un-filtering the list without losing track of the selected items within it. This is because during the filtration process, previously selected items are removed when they are "filtered out".
An alternative approach was trying a simple @for loop of mat-checkboxes. Yet, this method requires a costly function to determine the selected status of each item. Something like:
HTML
<mat-form-field class="w-full">
<mat-label>Filter</mat-label>
<input matInput formControlName="itemFilter" (ngModelChange)="filterItem($event)" />
</mat-form-field>
<div class="w-full flex-column my-list d-flex align-items-center justify-content-start">
@for(s of filteredOptions; track s){
<mat-checkbox class="w-full" [checked]="isSelected(s)" (click)="toggleSelected(s)">{{s.name}} ({{s.code}})</mat-checkbox>
}
</div>
Component
filterItem($event: any): void {
if (!$event) {
this.filteredOptions = this.origList;
}
if (typeof $event === 'string') {
this.filteredOptions = this.origList.filter((a) =>
a.name.toLowerCase().startsWith($event.toLowerCase())
);
}
}
isSelected(item: MyItem): boolean {
return (this.searchForm.get('selectedItems')?.value as MyItem[]).indexOf(item) > -1;
}
toggleSelectedShed(item: MyItem) {
const current = this.searchForm.get('selectedItems')
?.value as MyItem[];
if (current.indexOf(item) > -1) {
// Remove it
current.splice(current.indexOf(item), 1);
} else {
// Add it
current.push(item);
}
this.searchForm.get('selectedItems')?.patchValue(current);
}
This particular function runs for every individual item during any change.
Is there an alternative solution that allows for filtering without these limitations?
I have abandoned the idea of filtering to focus on a straightforward checkbox array. However, this too poses challenges. Here is a stackblitz link to illustrate my work: Stackblitz to my work