I am continuing to experiments with Angular. In this article I will demonstrate how to create a grid component using Angular.
The grid makes no assumption about the backing data array, but you have to specify the columns you want to bind to the grid. Once bound, the grid is sortable in both ascending and descending order.
As you can see from the code below, columns are passed in as an array of type Column. The column object contains a key used for lookup and a description used for display.
grid.ts
import {Component} from '@angular/core';
import {Column} from './column';
import {Sorter} from './sorter';
@Component({
selector: 'grid',
inputs: ['rows: rows','columns: columns'],
templateUrl: './components/grid/grid.html'
})
export class Grid {
columns:Array<Column>;
rows:Array<any>;
sorter: Sorter;
constructor(){
this.sorter = new Sorter();
}
sort(key){
this.sorter.sort(key, this.rows);
}
}
column.ts
export class Column{
name: string;
descr: string;
constructor(name,descr){
this.name = name;
this.descr = descr;
}
}
The sorting is moved out to a separate class and allows the user to toggle between ascending and descending sorting.
sorter.ts
export class Sorter{
direction:number;
key:string;
constructor(){
this.direction = 1;
}
sort(key,data){
if(this.key === key){
this.direction = this.direction * -1;
}
else{
this.direction = 1;
}
this.key = key;
data.sort((a,b) => {
if(a[key] === b[key]){
return 0;
}
else if(a[key] > b[key]){
return 1 * this.direction;
}
else{
return -1 * this.direction;
}
});
}
}
grid.html
<table class="table table-striped">
<thead>
<tr>
<td *ngFor="let col of columns"><a (click)="sort(col.name)">{{col.descr}}</a></td>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of rows">
<td *ngFor="let col of columns">{{row[col.name]}}</td>
</tr>
</tbody>
</table>
The above markup shows how the generic data array is bound to the array via column name lookups.
Finally, the code below shows how the grid can be used from an external page:
<grid [rows]="people" [columns]="columns"></grid>
The properties people and columns are defined as follows:
let people = [];
people.push({firstName:'Joe',lastName:'Jackson',age:20});
people.push({firstName:'Peter',lastName:'Smith',age:30});
people.push({firstName:'Jane',lastName:'Doe',age:50});
people.push({firstName:'Tim',lastName:'Smith',age:80});
let columns = [];
columns.push(new Column('firstName','First Name'));
columns.push(new Column('lastName','Last Name'));
columns.push(new Column('age','Age'));
Anyway, there you have it – an Angular grid!
As with my other components, a live demo is available here.
The code is also available on GitHub