Issue
I am making a project with Angular. First, I added a checkbox feature to my table. I can select any or all of the rows I want and process them. Then I added the filtering feature to my table. When I search by word, I show the appropriate ones in my table. The problem starts when I want to use both at the same time. I am filtering, when I select all the incoming filtered data, it selects the entire table, the filter feature does not work in the checkbox section, can you help me?
/html/
<mat-form-field class="example-full-width" style="font-size: 12px;">
<mat-label>Search</mat-label>
<mat-icon matPrefix>search</mat-icon>
<input type="search" matInput [(ngModel)]="search">
</mat-form-field>
<div class="table-responsive">
<table class="table table-hover table-bordered"
filterControl="true">
<thead class=" text-primary">
<th>
<mat-checkbox (change)="$event ? toggleAllRows() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<th> NO.</th>
<th >NAME.</th>
<th >SURNAME</th>
<th >E-MAIL</th>
<th >SCHOOL NAME</th>
</thead>
<tbody>
<tr
*ngFor="let person of dataPersonList | filter: search ; let i =index ">
<td>
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(person) : null"
[checked]="selection.isSelected(person)">
</mat-checkbox>
</td>
<td> {{i+1}}</td>
<td> {{person.name}} </td>
<td> {{person.surname}}</td>
<td> {{person.email}}</td>
<td> {{person.schoolName}}</td>
</tr>
</tbody>
</table>
</div>
/component/
/*TABLE FILTER */
search:string;
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataPersonList.length;
return numSelected === numRows;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
toggleAllRows() {
if (this.isAllSelected()) {
this.selection.clear();
return;
}
this.selection.select(...this.dataPersonList);
}
/pipe/
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(values: any, filter: string): any {
if (!filter || filter.length === 0) {
return values;
}
if (values.length === 0) {
return values;
}
return values.filter((value: any) => {
let name;
name = value.name.toLocaleUpperCase().indexOf(filter.toLocaleUpperCase()) !== -1;
let surname;
surname = value.surname.toLocaleUpperCase().indexOf(filter.toLocaleUpperCase()) !== -1;
let email;
email = value.email.toLocaleUpperCase().indexOf(filter.toLocaleUpperCase()) !== -1;
let schoolName;
schoolName = value.schoolName.toLocaleUpperCase('tr-TR').indexOf(filter.toLocaleUpperCase('tr-TR')) !== -1;
if (name || surname || email || schoolName ) {
return value;
}
});
}
}
Solution
Use filteredData
instead data
(see the API)
isAllSelected() {
const numSelected = this.selection.selected.length;
//here is filteredData
const numRows = this.dataSource.filteredData.length;
//here is >= not ===
return numSelected >= numRows;
}
masterToggle() {
// if there is a selection then clear that selection
if (this.isSomeSelected()) {
this.selection.clear();
} else {
//here also is filteredData
this.isAllSelected()
? this.selection.clear()
: this.dataSource.filteredData.forEach(row => this.selection.select(row));
}
}
Your forked stackblitz with a simple filter (button click make a filter/remove filter)
Answered By - Eliseo
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.