Data Table Cell Template
Ornamentum allows flexible customization of the table cells of the Grid (excluding the header and footer sections) or to format the data the table cells display.
If the user uses cell templating for more than one column, the user has to handel rowspan
on that cell manually by involving both rowSpan
and spanIndex
Please refer Product Type and Revenue column in Row Span example.
What You Will See
Sales Products
ID | Order Method Type | Retailer Type | Product Line | Product Type | Revenue | Quantity | Gross Margin |
---|
10 | Fax | Outdoors Shop | Camping Equipment | Cooking Gear | 59,628.66 | 489 | 0.34754797 |
Cooking Gear | 59,628.66 | ||||||
Cooking Gear | 59,628.66 | ||||||
15 | Fax | Outdoors Shop | Camping Equipment | Sleeping Bags | 87,728.96 | 352 | 0.39814629 |
20 | Telephone | Outdoors Shop | Camping Equipment | Lanterns | 6,940.03 | 109 | 0.36186587 |
Lanterns | 6,940.03 | ||||||
25 | Fax | Outdoors Shop | Mountaineering Equipment | Safety | 62,464.88 | 898 | 0.24468085 |
Safety | 62,464.88 | ||||||
30 | Web | Outdoors Shop | Mountaineering Equipment | Climbing Accessories | 19,476.80 | 296 | 0.47613982 |
35 | Web | Outdoors Shop | Mountaineering Equipment | Climbing Accessories | 4,621.68 | 262 | 0.51643991 |
40 | Telephone | Outdoors Shop | Mountaineering Equipment | Tools | 32,870.40 | 856 | 0.49166667 |
Tools | 32,870.40 | ||||||
45 | Telephone | Outdoors Shop | Personal Accessories | Knives | 30,940.25 | 275 | 0.28895209 |
50 | Telephone | Outdoors Shop | Outdoor Protection | First Aid | 4,057.20 | 180 | 0.60070985 |
55 | Telephone | Golf Shop | Personal Accessories | Watches | 7,939.80 | 66 | 0.44272652 |
import { Component } from '@angular/core'; import { ExampleData } from 'helper-models'; import { DataFetchService } from 'helper-services'; import { DataTableRow } from 'ornamentum'; @Component({ selector: 'app-cell-template-usage', templateUrl: './cell-template-usage.component.html' }) export class CellTemplateUsageComponent { public items: ExampleData[]; constructor(private dataFetchService: DataFetchService) { this.items = this.dataFetchService.fetchStaticData(); } public onDynamicRowSpanExtract(row: DataTableRow<ExampleData>): number { if (row.item.availableStores && row.item.availableStores.length) { return row.item.availableStores.length; } return 1; } public getStoreName(item: ExampleData, index: number, field: string) { return item.availableStores && item.availableStores[index] ? item.availableStores[index][field] : '-'; } }
<ng-data-table [id]="'sales_products_templating_07'" [title]="'Sales Products'" [items]="items" [minContentWidth]="1280" [pageable]="true" [showHeader]="true" [onDynamicRowSpanExtract]="onDynamicRowSpanExtract" [showColumnSelector]="true"> <ng-data-table-column [field]="'id'" [title]="'ID'" [width]="90"> </ng-data-table-column> <ng-data-table-column [field]="'orderMethodType'" [title]="'Order Method Type'" [width]="150"> </ng-data-table-column> <ng-data-table-column [field]="'retailerType'" [title]="'Retailer Type'" [width]="120"> </ng-data-table-column> <ng-data-table-column [field]="'productLine'" [title]="'Product Line'" [width]="180"> </ng-data-table-column> <ng-data-table-column [field]="'productType'" [title]="'Product Type'" [width]="160"> <ng-template #ngDataTableCell let-row="row" > <td style="color: #4dc71f;font-style: oblique"> <span>{{row.item.productType }}</span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'revenue'" [title]="'Revenue'" [width]="150"> <ng-template #ngDataTableCell let-row="row" > <td> <span>{{row.item.revenue | number:'3.2-5'}}</span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'quantity'" [title]="'Quantity'" [width]="120"> </ng-data-table-column> <ng-data-table-column [field]="'grossMargin'" [title]="'Gross Margin'" [width]="150"> </ng-data-table-column> </ng-data-table>
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { DataTableModule } from 'ornamentum'; import { CellTemplateUsageComponent } from './cell-template-usage.component'; @NgModule({ bootstrap: [CellTemplateUsageComponent], declarations: [CellTemplateUsageComponent], imports: [ BrowserModule, DataTableModule.forRoot() ] }) export class CellTemplateUsageModule { }
Basic Usage
Following code snippet depicts the integration of cell template. To define the cell template, nest an <ng-template>
tag with the ngDataTableCell
directive inside a <ng-data-table-column>
tag. The template context is set to the current data item and the following additional fields are passed.let-column="column" let-row="row" let-spanIndex="spanIndex" let-rowSpan="rowSpan"
<ng-template #ngDataTableCell let-column="column" let-row="row" let-spanIndex="spanIndex" let-rowSpan="rowSpan"> // your template goes here </ng-template>
<ng-template #ngDataTableCell let-row="row"> <td style="color: #4dc71f;font-style: oblique"> <span>{{row.item.productType}}</span> </td> </ng-template>
Useful Properties
There are few more configurations available that affect the cell templating behaviours.
Column
column: DataTableColumnComponent
Target Component: <ng-data-table-column>
To define the cell template, nest an <ng-template>
tag with the ngDataTableCell
directive inside a <ng-data-table-column>
tag.
The current column instance contains all column properties. Users can use it as an alias for a template variable by utilizing the let-column="column"
syntax.
<ng-template #ngDataTableCell let-column="column"> {{<--column properties can be accessed in here when providing custom template-->}} </ng-template>
Row
row: DataTableRow
Target Component: <ng-data-table-column>
To define the cell template, nest an <ng-template>
tag with the ngDataTableCell
directive inside a <ng-data-table-column>
tag.
The current row instance contains all the row data. Users can use it as an alias for a template variable by utilizing the let-row="row"
syntax.
<ng-template #ngDataTableCell let-row="row"> {{<--row properties can be accessed in here when providing custom template-->}} </ng-template>
Usage of row
property
Hall of Fame
ID | Name | Git Profile URL |
---|
5279079 | https://github.com/yohangz | |
6312524 | https://github.com/lahiruz | |
29842949 | https://github.com/aravindakr95 | |
35022498 | https://github.com/samudithaw | |
6813939 | https://github.com/cagline | |
43087732 | https://github.com/thaveeshagamage | |
24251976 | https://github.com/sanuradhag | |
3881403 | https://github.com/Arty26 |
import { Component } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { DataTableRequestParams, DataTableQueryResult } from 'ornamentum'; @Component({ selector: 'app-cell-template-avatar-usage', templateUrl: './cell-template-avatar-usage.component.html', styles: ['.highlight { color: lightblue; font-weight: bold;}'] }) export class CellTemplateAvatarUsageComponent { constructor(public http: HttpClient) { } /** * custom data provider need to return a function which is return an Observable out put * as long as your data return as observable you can use any data source * example : Firebase Realtime Database or Cloud Firestore */ public onDataBind = (params: DataTableRequestParams): Observable<DataTableQueryResult<any>> => { const page = (params.offset + params.limit) / params.limit; const perPage = params.limit; let httpParams = new HttpParams(); httpParams = httpParams .append('page', '' + page) .append('perPage', '' + perPage); return this.http.get('https://api.github.com/repos/yohangz/ornamentum/contributors', { params: httpParams }) .pipe(map((res: any) => { /** * Items collection * items: T[]; * Item count * count: number; */ return { items: res, count: res.length }; }) ) as Observable<any>; }; }
<ng-data-table [id]="'hall_of_fame_templating_01'" [title]="'Hall of Fame'" [limit]="10" [minContentWidth]="1280" [showHeader]="true" [pageable]="true" [showColumnSelector]="true" [onDataBind]="onDataBind"> <ng-data-table-column [field]="'id'" [title]="'ID'" [width]="90"> <ng-template #ngDataTableCell let-row="row"> <td style="vertical-align: middle"> <span [ngClass]="{'highlight': row.item.contributions > 500}">{{row.item.id}}</span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'login'" [title]="'Name'" [width]="200"> <ng-template #ngDataTableCell let-row="row"> <td style="vertical-align: middle"> <img style="width: 48px; height: 48px; border-radius: 50%; margin-right: 10px;" [src]="row.item.avatar_url"/> <span [ngClass]="{'highlight': row.item.contributions > 500}">{{row.item.login}}</span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'html_url'" [title]="'Git Profile URL'" [width]="200"> <ng-template #ngDataTableCell let-row="row"> <td style="vertical-align: middle"> <a [ngClass]="{'highlight': row.item.contributions > 500}" [href]="row.item.html_url">{{row.item.html_url}}</a> </td> </ng-template> </ng-data-table-column> </ng-data-table>
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { DataTableModule } from 'ornamentum'; import { CellTemplateAvatarUsageComponent } from './cell-template-usage-avatar.component'; @NgModule({ bootstrap: [CellTemplateAvatarUsageComponent], declarations: [CellTemplateAvatarUsageComponent], imports: [ BrowserModule, DataTableModule.forRoot() ] }) export class CellTemplateUsageAvatarModule { }
Span Index
spanIndex: number
Target Component: <ng-data-table-column>
To define the cell template, nest an <ng-template>
tag with the ngDataTableCell
directive inside a <ng-data-table-column>
tag.
The span index of the current row is useful when using row spanning. Users can use it as an alias for a template variable by utilizing the let-spanIndex="spanIndex"
syntax.
<ng-template #ngDataTableCell let-spanIndex="spanIndex"> {{<--spanIndex property can be accessed in here when providing custom template-->}} </ng-template>
Users will need this when using the Cell Templating for more than one column with row span. Users can find such a scenario in Row Span example for the usage of span index.
Row Span
rowSpan: number
Target Component: <ng-data-table-column>
To define the cell template, nest an <ng-template>
tag with the ngDataTableCell
directive inside a <ng-data-table-column>
tag.
Row Span of the current row is useful when using row span. Users can use it as an alias for a template variable by utilizing the let-rowSpan="rowSpan"
syntax.
<ng-template #ngDataTableCell let-rowSpan="rowSpan"> {{<--rowSpan property can be accessed in here when providing custom template-->}} </ng-template>
If the user is going to use cell templates for more than one column user has to handel rowspan
on that cell manually, with involving both rowSpan
and spanIndex
import { Component } from '@angular/core'; import { DataTableRow } from 'ornamentum'; import { ExampleData } from 'helper-models'; import { DataFetchService } from 'helper-services'; @Component({ selector: 'app-cell-template-row-span-usage', templateUrl: './cell-template-row-span-usage.component.html' }) export class CellTemplateRowSpanUsageComponent { public items: ExampleData[]; constructor(private dataFetchService: DataFetchService) { this.items = dataFetchService.fetchStaticData(); } public onDynamicRowSpanExtract(row: DataTableRow<ExampleData>): number { if (row.item.availableStores && row.item.availableStores.length) { return row.item.availableStores.length; } return 1; } public getStoreName(item: ExampleData, index: number, field: string) { return item.availableStores && item.availableStores[index] ? item.availableStores[index][field] : '-'; } }
<ng-data-table [id]="'sales_products_templating_07'" [title]="'Sales Products'" [items]="items" [minContentWidth]="1280" [pageable]="true" [showHeader]="true" [onDynamicRowSpanExtract]="onDynamicRowSpanExtract" [showColumnSelector]="true"> <ng-data-table-column [field]="'id'" [title]="'ID'" [width]="90"> </ng-data-table-column> <ng-data-table-column [field]="'orderMethodType'" [title]="'Order Method Type'" [width]="150"> </ng-data-table-column> <ng-data-table-column [field]="'retailerType'" [title]="'Retailer Type'" [width]="120"> </ng-data-table-column> <ng-data-table-column [field]="'productLine'" [title]="'Product Line'" [width]="180"> </ng-data-table-column> <ng-data-table-column [field]="'productType'" [title]="'Product Type'" [width]="160"> <ng-template #ngDataTableCell let-row="row" let-rowSpan="rowSpan" let-spanIndex="spanIndex"> <td style="color: #4dc71f;font-style: oblique" [attr.rowspan]="rowSpan" *ngIf="!spanIndex" > <span>{{row.item.productType }} #{{spanIndex}}</span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'revenue'" [title]="'Revenue'" [width]="150"> <ng-template #ngDataTableCell let-row="row" let-rowSpan="rowSpan" let-spanIndex="spanIndex"> <td [attr.rowspan]="rowSpan" *ngIf="!spanIndex" > <span>{{row.item.revenue | number:'3.2-5'}}</span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'availableStores'" [title]="'Available Stores'" [width]="120"> <ng-template #ngDataTableCell let-row="row" let-spanIndex="spanIndex"> <td> <span>{{(spanIndex + 1)}}) {{ getStoreName(row.item, spanIndex, 'storeName') }} </span> </td> </ng-template> </ng-data-table-column> <ng-data-table-column [field]="'quantity'" [title]="'Quantity'" [width]="120"> </ng-data-table-column> <ng-data-table-column [field]="'grossMargin'" [title]="'Gross Margin'" [width]="150"> </ng-data-table-column> </ng-data-table>
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { DataTableModule } from 'ornamentum'; import { CellTemplateRowSpanUsageComponent } from './cell-template-row-span-usage.component'; @NgModule({ bootstrap: [CellTemplateRowSpanUsageComponent], declarations: [CellTemplateRowSpanUsageComponent], imports: [ BrowserModule, DataTableModule.forRoot() ] }) export class CellTemplateRowSpanUsageModule { }
Suggested Links
Dynamic Row SpanAPI Doc for Data Table Cell Template