Kunal Vijan
Kunal Vijan

Reputation: 447

What should I use to get my updated count based on filter selection?

I am using CSV upload and display the data in the table along with using custom table filter pipe function.

How can I get the count of filtered based on filter section?

For e.g. Once you upload data considering your csv has 7 rows; it would be Showing 7 of 7 Records.

When you are filtering based on Gender male/female I should get Showing 4 of 7 Records or Showing 3 of 7 Records

I tried below I didn't get the results.

Showing {{filteredUsers.length}} of {{dataList.length}} Records

If I am doing like:

<strong class="ml-3" *ngFor="let record of dataList | tableFilter: form.value as filteredUsers">
Showing {{filteredUsers.length}} of {{dataList.length}} Records
</strong>

I am getting the count n updating as well based on the filter selection but it's repeating based on the number of rows so, coming 7 times.

app.component.html

<form #form="ngForm">
<select class="form-control form-control-sm" name="gender" ngModel>
<option value="" selected>All</option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</form>

<tr *ngFor="let record of dataList | tableFilter: form.value as filteredUsers">
<td> {{record.name}} </td>
<td> {{record.gender}} </td>
</tr>

Live: https://stackblitz.com/edit/angular-csv-parser-aazvnq?file=app%2Fapp.component.html

CSV Sample

enter image description here

Upvotes: 2

Views: 543

Answers (2)

Nicholas K
Nicholas K

Reputation: 15443

Make the following changes:

The basic change added here is introducing another variable selectedCount that will hold the count of selected items based on the dropdown values.

app.component.html

Showing {{selectedCount}} of {{dataList.length}} Records

<div>
    <form #form="ngForm">
        <select class="form-control form-control-sm" name="gender" 
               [(ngModel)]="dropDown" (change)="dropDownChange()">
                    <option value="All">All</option>
                    <option value="male">Male</option>
                    <option value="female">Female</option>
        </select>
    </form>
</div>

app.component.ts

  dropDown = "All";
  public selectedCount = this.dataList.length;

  dropDownChange() {
    if (this.dropDown !== "All") {
      this.selectedCount = this.dataList.filter(
        e => e.gender === this.dropDown
      ).length;
    } else {
      this.selectedCount = this.dataList.length;
    }
  }

table.filter.pipe.ts

export class TableFilterPipe implements PipeTransform {
  transform(list: any[], filters: any) {
    if (filters.gender !== "All") {
      const keys = Object.keys(filters).filter(key => filters[key]);
      const filterUser = user => keys.every(key => user[key] === filters[key]);
      return keys.length ? list.filter(filterUser) : list;
    } else {
      return list;
    }
  }
}

Working stackblitz found here.

Upvotes: 1

Moshezauros
Moshezauros

Reputation: 2593

I suggest a slightly different approach than Nicholas's solution - instead of updating two items every time a change is made, you can have the pipe function update the variable which represents the count - this way, a single place is responsible of handling both the count and the filtering, this requires adding an object in the component:

countObj = { count: 0 };

in the template:

Showing {{countObj.count}} Records
...
<tr *ngFor="let record of dataList | tableFilter: form.value:countObj">

and in the transform function:

  transform(list: any[], filters: Object, countObj: any) {
    const keys = Object.keys(filters).filter(key => filters[key]);
    const filterUser = user => keys.every(key => user[key] === filters[key]);

    if (keys.length) {
      const res = list.filter(filterUser);
      countObj.count = res.length;
      return res;
    } else {
      countObj.count = list.length;
      return list;
    }
  }

working stackblitz

Upvotes: 1

Related Questions