Advance Filter

Advance Filter

By krish ghatul

let discuss filter with angular 5. I hope You know about inbuilt angular filters like date filter.

For example. (Inbuilt filters).

<h4>2. My name is {{ABC | lowercase}}< /h4> 

<h4>2. Today is {{today | date}} </h4>

<h4>3. Today is {{today | date:"DD/MM/yyyy"}} /h4>


In this tutorial, We are going to learn How to build our own custom (Advance filter) with angular. We are going to use a pipe for building a custom filter, and I hope, You know about the custom pipe and how it works. If you don't know, please learn about angular pipes and how it works.

Let's take one example, employee. (Employee. ts)

export class Employee {
 firstName: string;
 lastName: string;
 age: number;
 salaryRange: string;
 experienceRange: string;
 companyName: string;
 city: string;
 education: string;
}

Suppose we are having a list of employees and we want to filter them using their skills or some attributes. For example, I want employee age<30 and education=”Graduate”. Here each time you need to create query dynamically and pass to filter employees.

How can you do that? Let's do it….

Download complete source code from: https://github.com/ghatul/Advance-Filter


Step 1: Create pipe (emp-card-filter.pipe.ts)

import {Pipe, PipeTransform} from "@angular/core";
import {Employee} from "../model/employee";
import {CardFilter} from "../model/card-filter";

@Pipe({name: 'cardfilter', pure: false})

export class EmpCardFilterPipe implements PipeTransform {
 transform(array: Array<Employee>, args: CardFilter, cardObj: any): Array<any> {
   if (array === null) {
     return null;
   }
   if (args.query) {
     var result: Employee[];
     result = array.filter(item => eval(args.query));
     cardObj.count = result.length;
     return result;
   }
   cardObj.count = array.length;
   return array;
 }
}

cardfilter.ts

export class CardFilter {
 education: string[] = new Array(0);
 ageLimit: number;
 query: any;
 cardCount: any;
}

Step 2: Create Filter Component (filter.component.ts/.html/.css)

1. filter.component.html

<div><label> Card Count</label>{{CardObj.count}}
<div><label>Education</label><div *ngFor="let item of education">
   <label>
     <input type="checkbox" formControlName="eduction" value="{{item}}"
            (change)="filterByEducation($event)">{{item}}
   </label></div>
</div>
<div><label>Age</label><select formControlName="age" (change)="sortByAge($event.target.value)">
   <option value="" selected></option>
   <option value="{{item}}"
           *ngFor="let item of age ">{{item}}
   </option></select>
</div>
</div>

2.filter.component.ts

import {Component, EventEmitter, Input, OnInit, Output} from "@angular/core";
import {CardFilter} from "../../model/card-filter";

@Component({
 selector: 'app-filter',
 templateUrl: './filter.component.html',
 styleUrls: ['./filter.component.css']
})
export class FilterComponent implements OnInit {
 age = ['20', '30', '40', '45', '50', '55'];
 education = ['Under Graduate', 'Graduate', 'Post Graduate'];
 cardFilter: CardFilter = new CardFilter();
 private queryList: string[] = new Array(0);
 qeryString = '';
 @Output() filterQryChange: EventEmitter<CardFilter> = new EventEmitter<CardFilter>();
 @Input() CardObj: any;

 filterByEducation(event: any)  {
   var value = event.target.value;
   if (value == '') {
     this.queryRemove('(args.education.indexOf(item.education) !== -1)');
   }
   if (event.target.checked) {
     this.cardFilter.education.push(value);
   } else {
     var index = this.cardFilter.education.indexOf(value);
     if (index > -1) {
       this.cardFilter.education.splice(index, 1);
     }
   }
   if (this.cardFilter.education.length) {
     this.queryPush('(args.education.indexOf(item.education) !== -1)');
   } else {
     this.queryRemove('(args.education.indexOf(item.education) !== -1)');
   }
   this.buildFilterQuery();
 }
 sortByAge(value: string) {
   if (value === '') {
     this.queryRemove('(((args.ageLimit && item.age))&&(args.ageLimit >= item.age))');
   } else if (value) {
     this.cardFilter.ageLimit = Number(value);
     this.queryPush('(((args.ageLimit && item.age))&&(args.ageLimit >= item.age))');
   }
   this.buildFilterQuery();
 }
 queryPush(query: string) {
   if (this.queryList.indexOf(query) == -1) {
     this.queryList.push(query);
   }
 }
 queryRemove(query: string) {
   var i = this.queryList.indexOf(query);
   if (i != -1) {
     this.queryList.splice(i, 1);
   }
 }
 buildFilterQuery() {
   var query = 'true';
   for (var i = 0; i < this.queryList.length; i++) {
     query = query + '&&' + this.queryList[i];
   }
   this.cardFilter.query = query;
   this.filterQryChange.emit(this.cardFilter);
 }}

queryPush -> is a function used to add a query for operation.

queryRemove -> is a function used to remove query for operation.

buildFilterQuery -> is a function used to build a final query.

Above filter, component shows you how to create a dynamic query. Each fields having its own query hence on each action you need to decide add or remove query from that list.

  1. EmpCardFilterPipe.ts

Role:- Custom pipe which is used to filter employee list.(Filter name cardfilter)

2. CardFilter.ts

           Role:- Model(object/class) used as metadata for EmpCardFilterPipe.

3. filter.component.ts/.html/.css

           Role:- Build CardFilter object having a query and other criterias.

4. employee.component.ts/.html/.css

           Role:- Used to show employee card list.

           Code: <ul *ngFor="let emp of empData | cardfilter:fiterObj:cardObj">

5. Employee.ts

           Role:- Employee list data is a type of Employee.

Here fiterObj is a type of CardFilter. filterObj is used as metadata for cardfilter it contains all applied criterias on employee list and query.filterObj is a type of CardFilter.

cardObj is a type of {“count”:0} is used to show filtered list count.

Note: It just my idea(code) and you can edit, update, expand this code with your own concepts.

Suggestion:- Performance issue with huge data. So, use when data is less.

Download complete source code from: https://github.com/ghatul/Advance-Filter

Swapnil Nakhate

Sr. Fullstack Developer at SA Technologies

7 年

Very helpful..

回复

要查看或添加评论,请登录

krishna ghatul的更多文章

社区洞察

其他会员也浏览了