0

Currently, I have a Gender and Impact filter to the table which is able to filter the data on option selected.

For e.g. If you will select Male it will filter male data and the same for female, impact: applicable and not applicable.

Now, I wanted to add an apply button that will join both of them together and filter. Once clicked on the apply button that will filter data combination of both.

enter image description here

enter image description here

Can anyone please help me with the requirement?

Code:

<div class="filter-data clearfix">
    <form #form="ngForm">
      <div class="form-group float-left mr-4">
        <strong>Gender</strong>
        <br>
        <select class="form-control form-control-sm" name="gender" ngModel>
          <option></option>
          <option value="Male">Male</option>
          <option value="Female">Female</option>
        </select>
      </div>
      <div class="form-group float-left">
        <strong>Impact</strong>
        <br>
        <select class="form-control form-control-sm" name="impact" ngModel>
          <option></option>
          <option value="Applicable">Applicable</option>
          <option value="Not Applicable">Not Applicable</option>
        </select>
      </div>
      <div class="form-group float-left mt-4 ml-2">
        <button type="button" class="btn btn-primary btn-sm mr-2">Apply</button>
        <button type="button" class="btn btn-secondary btn-sm">Reset</button>
      </div>
    </form>
  </div>

<table class="table table-sm table-responsive">
      <thead>
        <tr>
          <th>
            <input type="checkbox" name="allNonTrades" (change)="selectAllClicked($event)">
          </th>
          <th>First Name</th>
          <th>Last Name</th>
          <th>Email</th>
          <th>Gender</th>
          <th>DOB</th>
          <th>Impact</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr class="record-row" (click)="viewUser(user)" *ngFor="let user of allUser | tableFilter: form.value | paginate: { id: 'listing_pagination', itemsPerPage: 10, currentPage: page, totalItems: totalRecords }">
          <td><input *ngIf="!isEdit"  name="nontrades" [checked]="user.selected" (change)="changeTradesByCategory($event)" [(ngModel)]="user.checked" type="checkbox" (change)="checkboxClicked()"></td>
          <td>{{user.first_name}}</td>
          <td>{{user.last_name}}</td>
          <td>{{user.email}}</td>
          <td>{{user.gender}}</td>
          <td>{{user.dob}}</td>
          <td>{{user.impact}}</td>
          <td>
            <button *ngIf="!isEdit" class="btn btn-primary btn-sm" (click)="editUser(user)">Edit</button>
            <button class="btn btn-primary btn-sm btn-sm ml-2" (click)="deleteUser(user)">Delete</button>
          </td>
        </tr>
      </tbody>
    </table>

table-filter.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'tableFilter'
})

export class TableFilterPipe implements PipeTransform {
  transform(list: any[], filters: Object) {
    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;
  }
}
Kunal Vijan
  • 425
  • 2
  • 9
  • 28

1 Answers1

2

Just add [ngModelOptions]="{updateOn: 'submit'}" in gender and impact select tags. This let form.value to update only on submit and thus changing tableFilter: form.value and filter is applied accordingly.

<select class="form-control form-control-sm" name="gender" ngModel [ngModelOptions]="{updateOn: 'submit'}">


<select class="form-control form-control-sm" name="impact" ngModel [ngModelOptions]="{updateOn: 'submit'}">

Lastly change Apply Button type to submit

<button type="submit" class="btn btn-primary btn-sm mr-2">Apply</button>
Arun
  • 468
  • 3
  • 6
  • I wanted to bring one more filter as a date range. `` How can I make that data filter to show DOB results matching that range? – Kunal Vijan Dec 19 '20 at 10:48
  • can you please help me what changes do I need to make in my table-filter.pipe so, that it will show the results matching that range? – Kunal Vijan Dec 19 '20 at 11:39
  • const filterUser = user => keys.every(key => user[key] === filters[key]); here u have to do the changes. – Arun Dec 19 '20 at 11:47
  • I am not very good in this. It would be really helpful if you can spend few more mins and do I change as I don't know what changes do I have do. – Kunal Vijan Dec 19 '20 at 11:49
  • 1
    Try this`const filterUser = user => keys.every(key => { if(key == 'dob') {const sDate=new Date(user[key].split(' - ')[0]); const eDate=new Date(user[key].split(' - ')[1]); const date = new Date(user[key]); return date > sDate && date< eDate } else{ return user[key] === filters[key]} })`and Change select for DOB name='dob' – Arun Dec 19 '20 at 12:46
  • what would be the value in options? `` – Kunal Vijan Dec 19 '20 at 14:02
  • I am getting in the console as an Invalid date for sDate, eDate – Kunal Vijan Dec 19 '20 at 14:17
  • I tried ` ` but no luck – Kunal Vijan Dec 19 '20 at 14:22
  • 1
    Done changes select to input type date Min & Max for date Range and changed TableFilterPipe. Check [StackBlitz][1] link.Lost actual asked in question link so adding here. [1]: https://stackblitz.com/edit/angular-ivy-mriubn?file=src/app/table-filter.pipe.ts – Arun Dec 19 '20 at 19:54
  • If I am selecting the same date in start date n end date it's not showing up the result to me https://stackblitz.com/edit/angular-ivy-mriubn?file=src/app/table-filter.pipe.ts for e.g. 01/01/1987 – Kunal Vijan Dec 22 '20 at 13:40