In angular 2 we don't have pre-defined filter and order by as it was with AngularJs, we need to create it for our requirements. It is time killing but we need to do it, (see No FilterPipe or OrderByPipe). In this article we are going to see how we can create filter called pipe in angular 2 and sorting feature called Order By. Let's use a simple dummy json data array for it. Here is the json we will use for our example
First we will see how to use the pipe (filter) by using the search feature:
Create a component with name category.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-category',
templateUrl: './category.component.html'
})
export class CategoryComponent implements OnInit {
records: Array<any>;
isDesc: boolean = false;
column: string = 'CategoryName';
constructor() { }
ngOnInit() {
this.records= [
{ CategoryID: 1, CategoryName: "Beverages", Description: "Coffees, teas" },
{ CategoryID: 2, CategoryName: "Condiments", Description: "Sweet and savory sauces" },
{ CategoryID: 3, CategoryName: "Confections", Description: "Desserts and candies" },
{ CategoryID: 4, CategoryName: "Cheeses", Description: "Smetana, Quark and Cheddar Cheese" },
{ CategoryID: 5, CategoryName: "Grains/Cereals", Description: "Breads, crackers, pasta, and cereal" },
{ CategoryID: 6, CategoryName: "Beverages", Description: "Beers, and ales" },
{ CategoryID: 7, CategoryName: "Condiments", Description: "Selishes, spreads, and seasonings" },
{ CategoryID: 8, CategoryName: "Confections", Description: "Sweet breads" },
{ CategoryID: 9, CategoryName: "Cheeses", Description: "Cheese Burger" },
{ CategoryID: 10, CategoryName: "Grains/Cereals", Description: "Breads, crackers, pasta, and cereal" }
];
// this.sort(this.column);
}
}
Nothing special in this code just initialize our records variable with a list of categories, two other variables isDesc and column are declared which we will use for sorting latter. At the end added this.sort(this.column);
latter we will use, once we will have this method.
Note templateUrl: './category.component.html', which we will create next to show the records in tabluar format.
For this create a HTML page called category.component.html, whith following code:
<div class="col-md-12">
<table class="table table-responsive table-hover">
<tr>
<th >Category ID</th>
<th>Category</th>
<th>Description</th>
</tr>
<tr *ngFor="let item of records">
<td>{{item.CategoryID}}</td>
<td>{{item.CategoryName}}</td>
<td>{{item.Description}}</td>
</tr>
</table>
</div>
Here we use ngFor to repeat the records and show row by row, try to run it and we can see all records in a table.
Search - Filter Records
Say we want to search the table by category name, for this let's add one text box to type and search
<div class="form-group">
<div class="col-md-6" >
<input type="text" [(ngModel)]="searchText"
class="form-control" placeholder="Search By Category" />
</div>
</div>
Now we need to create a pipe to search the result by category because filter is not available as it was in angularjs any more.
Create a file category.pipe.ts and add following code in it.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'category' })
export class CategoryPipe implements PipeTransform {
transform(categories: any, searchText: any): any {
if(searchText == null) return categories;
return categories.filter(function(category){
return category.CategoryName.toLowerCase().indexOf(searchText.toLowerCase()) > -1;
})
}
}
Here in transform method we are accepting the list of categories and search text to search/filter record on the list. Import this file into our category.component.ts file, we want to use it here, as follows:
import { CategoryPipe } from './category.pipe';
@Component({
selector: 'app-category',
templateUrl: './category.component.html',
pipes: [CategoryPipe] // This Line
})
Our ngFor loop now need to have our Pipe to filter the records so change it to this
<tr *ngFor="let item of records | category: searchText">
Try it and it will filter the record with our entered text into search text box.
Sort - Order By: on table columns
We will use font-awesome icone to show the sort direction, for it we are going to use
We need to use these classes conditionally, for it we need two value sorting property say column
and sort direction say isDesc
, which already declared in our controller. Default sorting by CategoryName and direction ascending.
Let's see how we can apply these three classes conditionally:
<i class="fa"
[ngClass]="{'fa-sort': column != 'CategoryID',
'fa-sort-asc': (column == 'CategoryID' && !isDesc),
'fa-sort-desc': (column == 'CategoryID' && isDesc) }"
aria-hidden="true"> </i>
Add this line in every header (th) and change the conditoin with column name to show the direction, let me clear it, not very difficult:
Add click event to every header to change the sorted column and direction on every click and sort the records.
<th class="pointer" (click)="sort('CategoryID')"> // category Id
<th class="pointer" (click)="sort('CategoryName')" > // Category Name
<th class="pointer" (click)="sort('Description')" > // Description
We added here a class pointer to change the mouse cursor to show hand and call the sort function on click and pass the column name.
// CSS class to change the mouse cursor in hand
.pointer{
cursor: pointer;
}
We need to define our sort function so let's to do it.
sort(property){
this.isDesc = !this.isDesc; //change the direction
this.column = property;
let direction = this.isDesc ? 1 : -1;
this.records.sort(function(a, b){
if(a[property] < b[property]){
return -1 * direction;
}
else if( a[property] > b[property]){
return 1 * direction;
}
else{
return 0;
}
});
};
When I was testing I found it is working well without filter but once I add the filter, it stop showing any result. To fix this let's make some changes and move our sorting funtion to a pipe.
Here is the changes in our above code:
// Declare local variable
direction: number;
// Change sort function to this:
sort(property){
this.isDesc = !this.isDesc; //change the direction
this.column = property;
this.direction = this.isDesc ? 1 : -1;
}
Create a new orderBy pipe and move all the sorting featur to it, here is complete pipe code:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'orderBy' })
export class OrderrByPipe implements PipeTransform {
transform(records: Array<any>, args?: any): any {
return records.sort(function(a, b){
if(a[args.property] < b[args.property]){
return -1 * args.direction;
}
else if( a[args.property] > b[args.property]){
return 1 * args.direction;
}
else{
return 0;
}
});
};
}
Here nothing is new just we moved the code to a pipe for better user.
We need to import both the pipes into our app.module.ts file, add them in declarations section
import { CategoryPipe } from './directives/category.pipe';
import { OrderrByPipe } from './directives/orderby.pipe';
@NgModule({
declarations: [
AppComponent,
............
CategoryPipe, // Note these two line
OrderrByPipe, // Note these two line
],
imports: [
.........
],
providers: [.......],
bootstrap: [AppComponent]
})
It's recomended to import and add the pipes into declarations section so it can be accessible from entire application, if we want to use only from a single page then we can use the pipes: [....] and it will be available for that component only.
Now time to give the final tough for our orderBy, change the ngFor like this:
<tr *ngFor="let item of records | category: searchText
| orderBy: {property: column, direction: direction}">
Now we nicely completed it. Any suggestion or question is most welcome.
![]() |
Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
|
By Ali Adravi On 16 Apr, 17 Viewed: 83,687 |
Add/Edid Customer in Modal Popup --- In previous article we discussed how to search, delete and show detail of customer and contact list. In this article we will try to open the modal popup to add new customer and edit an existing customer record. I divided article in two parts because of the... By Ali Adravi On 29 Jul 2015 Viewed: 19,499
Angularjs custom directives are the common to avoid the duplicate code, it is easy powerful and really nice. There are already too many directive have been created by experts but as a developer we need to write our own to achieve our specific goal. ng-model, ng-if, ng-show, ng-repeat all these are... By Ali Adravi On 29 Jul 2015 Viewed: 4,471
Search sort Insert update and delete are the basic features we need to learn first to learn any language, In this article we will try to create these features with Web API, bootstrap modal popup and ui.router. We will use enetity framework code first to save and retrieve data from database. We... By Ali Adravi On 28 Jul 2015 Viewed: 31,236
Progress bar for Angularjs application by using directives is simple and real easy. I was googling and could not found any directive way, if you will check most of the people says before call the http method open the progress bas and close once you get the result or get any error. Do you think it... By Ali Adravi On 24 Jul 2015 Viewed: 14,166
Angularjs animation is more than easy, even you don't have write a single line of code any kind of animation. In this demo I am going to show how you can animate the list of item coming from left, rotating and flying list items by just adding ngAnimation dependency and some copy and past of css and... By Ali Adravi On 21 Jul 2015 Viewed: 2,428