I am using the clarity datagrid and I want to be able to filter based on a search filter the entire grid content.
I tried to create a pipe. The pipe is included inside the app.module. The pipe is called the first time the component is loaded (and nothing is supposed to happen), but for some reason, when I put something into my , nothing is happening. No call to the 'userFilter' pipe.
user.component.html
<input type="text" id="search" placeholder="Search..." ([ngModel])="searchTerm">
...
<clr-dg-row *clrDgItems="let user of users | userFilter: searchTerm" [clrDgItem]="user" (click)="backupSelectedUser(user)">
<clr-dg-cell>{{ user.username }}</clr-dg-cell>
<clr-dg-cell>{{ user.name }}</clr-dg-cell>
<clr-dg-cell>{{ user.firstName }}</clr-dg-cell>
</clr-dg-row>
...
search.pipe.ts
transform(items: any, term: any): any {
if (term === undefined) {
return items;
}
return items.filter(function (item) {
for (const property in item) {
if (item[property] === null) {
continue;
}
if (item[property].toString().toLowerCase().includes(term.toLowerCase())) {
return true;
}
}
return false;
});
}
UPDATE: I did a little typo for the ngModel. It should be [(ngModel)] instead!
I remember writing a plunker showing exactly this a few months back: https://plnkr.co/edit/59FZKya2Soa7Ofnlge3B?p=preview
Based on what you described, this is exactly what you want. You should not use pipes like you are doing now in iterators, because it forces Angular to recompute them for every change detection, which is way too heavy. So the recommended solution is to stick with *clrDgItems="let user of users"
, and set the users
property itself to the filtered-down array, so that you only recompute the filter result when the user types something.