UNPKG

@notiz/ngx-tablo

Version:

JSON powered material table for Angular

244 lines (206 loc) 5.8 kB
# ngx-tablo [![npm version](https://badge.fury.io/js/@notiz%2Fngx-tablo.svg)](https://www.npmjs.com/package/@notiz/ngx-tablo) ## Installation Install `ngx-tablo` and add [@angular/material](https://material.angular.io/guide/getting-started#install-angular-material). ```bash npm i @notiz/ngx-tablo ``` Import `Tablo` in your component. ```ts import { Component } from '@angular/core'; import { Tablo, TabloColumns } from '@notiz/ngx-tablo'; interface User { name: string; age: number; } @Component({ selector: 'niz-default', standalone: true, imports: [Tablo], template: ` <ngx-tablo [data]="users" [columns]="columns"></ngx-tablo> `, styles: [], }) export class DefaultComponent { users: User[] = [ ... ]; columns: TabloColumns<User> = [ { header: 'Name', columnName: 'name', }, { header: 'Age', columnName: 'age', }, ]; } ``` Now add the `<ngx-tablo></ngx-tablo>` component in your template. ```html <ngx-tablo [data]="data" [columns]="columnsConfig" [showPaging]="true" (rowClick)="rowClick($event)" (sortChange)="sortChange($event)" (pageChange)="pageChange($event)" ></ngx-tablo> ``` ```ts import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { PageEvent } from '@angular/material/paginator'; import { Sort } from '@angular/material/sort'; import { Tablo, TabloColumns } from '@notiz/ngx-tablo'; import { CustomDataSource } from '../custom-data-source'; import { PeriodicElement, customerData, Customer } from '../example.data'; @Component({ selector: 'niz-home', standalone: true, imports: [Tablo], template: ` <div> <mat-form-field class="w-full" appearance="fill"> <mat-label>Search</mat-label> <span matPrefix class="material-icons"> search </span> <input type="search" matInput [(ngModel)]="search" /> </mat-form-field> <mat-spinner class="mx-auto" *ngIf="dataSource.loading$ | async" ></mat-spinner> <ngx-tablo *ngIf="!(dataSource.loading$ | async)" [dataSource]="dataSource" [columns]="columnsConfig" [showPaging]="true" [filter]="search" [resetPageOnSort]="true" [filterPredicate]="customFilter" (rowClick)="rowClick($event)" (sortChange)="sortChange($event)" (pageChange)="pageChange($event)" ></ngx-tablo> <ng-template #test let-row="row"> <span class="rounded-full bg-red-100 px-2 py-1 text-red-600"> {{ row.symbol }} </span> </ng-template> </div> <h2 class="text-2xl font-semibold">Users</h2> <ngx-tablo [data]="customerData" [columns]="customerColumns"></ngx-tablo> `, styles: [], }) export class HomeComponent implements OnInit { @ViewChild('test', { static: true }) test!: TemplateRef<any>; search = ''; dataSource!: CustomDataSource; columnsConfig: TabloColumns<PeriodicElement> = [ { columnName: 'position', header: 'No.', sort: true, }, { columnName: 'name', header: 'Name', cell: (element) => element.name, }, { columnName: 'weight', header: 'Weight', cell: (element) => element.weight, format: { currency: 'EUR', }, }, { columnName: 'symbol', header: 'Symbol', cell: (element) => element.symbol, lifecycle: { onInit: (column) => (column!.cellTemplate = this.test), }, }, { columnName: 'discoveredAt', header: 'Discovered', format: { date: 'dd.MM.yyyy' }, }, { columnName: 'meta.radioactive', header: 'Radioactive' }, ]; rowClick(row: PeriodicElement) { console.log(row); } sortChange(sort: Sort) { console.log('sortChange', sort); } pageChange(page: PageEvent) { console.log('pageChange', page); } customFilter(data: PeriodicElement, filter: string): boolean { return data.name.toLowerCase().includes(filter.toLowerCase()); } } ``` ## Display Cell Content ### Default Content The default content will be the data property value based on the `columnName` -> `row[columnName]`. ```ts import { Component } from '@angular/core'; import { Tablo, TabloColumns } from '@notiz/ngx-tablo'; @Component({ selector: 'niz-default', standalone: true, imports: [Tablo], template: ` <ngx-tablo [data]="data" [columns]="columns"></ngx-tablo> `, styles: [], }) export class DefaultComponent { data = [ { name: 'Tom Cook', }, ]; columns: TabloColumns<any> = [ { header: 'Name', columnName: 'name', }, ]; } ``` In this [example](./src/app/examples/default/default.component.ts) the column displays the data value `name` for each row. If the `columnName` doesn't match a property in the data the cell remains empty. ### Nested Content The above example works only if the property is a primitive value. What if your data contains nested objects? How to access a property inside an object? ```ts import { Component } from '@angular/core'; import { Tablo, TabloColumns } from '@notiz/ngx-tablo'; @Component({ selector: 'niz-nested', standalone: true, imports: [Tablo], template: ` <ngx-tablo [data]="data" [columns]="columns"></ngx-tablo>`, styles: [], }) export class NestedComponent { data = [ { name: 'Tom Cook', address: { street: 'Onion Park', }, }, ]; columns: TabloColumns<any> = [ { header: 'Name', columnName: 'name', }, { header: 'Street', columnName: 'address.street' }, ]; } ``` In this [example](./src/app/examples/nested/nested.component.ts) the data contains an `address` object. Display the street in the cell by adding the object name followed with a dot to the `columnName`.