How to install and use ng-table in Angular 6/7 ?

  Angular, Javascript

Using this ng-table and working with tables data is very easy. There are only simple table with 3 plugins/directives: filteringpagingsorting. You don’t need special config variable for storing settings for all plugins as is used in demo example. It’s just showing usage sample.

How to install?

npm install ng-table@latest

Don’t forget to add Ng2TableModule in main module

import { Ng2TableModule } from 'ng2-table/ng2-table';

Component.html

<section class="container-fluid">

<br>
<div class="row">
<div class="col-md-4">
<input *ngIf="config.filtering" placeholder="Filter all columns"
[ngTableFiltering]="config.filtering"
class="form-control"
(tableChanged)="onChangeTable(config)"/>
</div>
</div>

<ng-table [config]="config"
(tableChanged)="onChangeTable(config)"
(cellClicked)="onCellClick($event)"
[rows]="rows" [columns]="columns">
</ng-table>
<pagination *ngIf="config.paging"
class="pagination-sm"
[(ngModel)]="page"
[totalItems]="length"
[itemsPerPage]="itemsPerPage"
[maxSize]="maxSize"
[boundaryLinks]="true"
[rotate]="false"
(pageChanged)="onChangeTable(config, $event)"
(numPages)="numPages = $event">
</pagination>
<pre *ngIf="config.paging" class="card card-block card-header">Page: {{page}} / {{numPages}}</pre>


</section>

Component.ts

import { Component, OnInit } from '@angular/core';
import { TableData } from '../../table-data';

@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']})
export class TableComponent implements OnInit {

public rows:Array<any> = [];
public columns:Array<any> = [
{title: 'Name',
name: 'name',
className: ['bg-dark','text-white'],
filtering: {filterString: '', placeholder: 'Filter by name'}
},
{
title: 'Position',
name: 'position',
sort: false,
className: ['bg-dark','text-white'],
filtering: {filterString: '', placeholder: 'Filter by position'}
},
{
title: 'Office',
className: ['office-header','bg-dark','text-white'],
name: 'office',
sort: 'asc',

},
{
title: 'Extn.',
name: 'ext',
sort: '',
className: ['bg-dark','text-white'],
filtering: {filterString: '', placeholder: 'Filter by extn.'}
},
{
title: 'Start date',
className: ['bg-dark','text-white'],
name: 'startDate'
},
{
title: 'Salary ($)',
name: 'salary',
className: ['bg-dark','text-white'],


}
];
public page:number = 1;
public itemsPerPage:number = 5;
public maxSize:number = 5;
public numPages:number = 1;
public length:number = 0;


public config:any = {
paging: true,
sorting: {columns: this.columns},
filtering: {filterString: ''},
className: ['table-striped', 'table-bordered'] };

private data:Array<any> = TableData;

public constructor() {
this.length = this.data.length;
}

public ngOnInit():void {
this.onChangeTable(this.config);
}

public changePage(page:any, data:Array<any> = this.data):Array<any> {
let start = (page.page - 1) * page.itemsPerPage;
let end = page.itemsPerPage > -1 ? (start + page.itemsPerPage) : data.length;
return data.slice(start, end);
}

public changeSort(data:any, config:any):any {
if (!config.sorting) {
return data;
}

let columns = this.config.sorting.columns || [];
let columnName:string = void 0;
let sort:string = void 0;

for (let i = 0; i < columns.length; i++) {
if (columns[i].sort !== '' && columns[i].sort !== false) {
columnName = columns[i].name;
sort = columns[i].sort;
}
}

if (!columnName) {
return data;
}

// simple sorting
return data.sort((previous:any, current:any) => {
if (previous[columnName] > current[columnName]) {
return sort === 'desc' ? -1 : 1;
} else if (previous[columnName] < current[columnName]) {
return sort === 'asc' ? -1 : 1;
}
return 0;
});
}

public changeFilter(data:any, config:any):any {
let filteredData:Array<any> = data;
this.columns.forEach((column:any) => {
if (column.filtering) {
filteredData = filteredData.filter((item:any) => {
return item[column.name].match(column.filtering.filterString);
});
}
});

if (!config.filtering) {
return filteredData;
}

if (config.filtering.columnName) {
return filteredData.filter((item:any) =>
item[config.filtering.columnName].match(this.config.filtering.filterString));
}

let tempArray:Array<any> = [];
filteredData.forEach((item:any) => {
let flag = false;
this.columns.forEach((column:any) => {
if (item[column.name].toString().match(this.config.filtering.filterString)) {
flag = true;
}
});
if (flag) {
tempArray.push(item);
}
});
filteredData = tempArray;

return filteredData;
}

public onChangeTable(config:any, page:any = {page: this.page, itemsPerPage: this.itemsPerPage}):any {
if (config.filtering) {
Object.assign(this.config.filtering, config.filtering);
}

if (config.sorting) {
Object.assign(this.config.sorting, config.sorting);
}

let filteredData = this.changeFilter(this.data, this.config);
let sortedData = this.changeSort(filteredData, this.config);
this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;
this.length = sortedData.length;
}

public onCellClick(data: any): any {
console.log(data);
}
}






Create table.ts file in root folder and add it

export const TableData:Array<any> = [
{
'name': 'Victoria Cantrell',
'position': 'Integer Corporation',
'office': 'Croatia',
'ext': `<strong>0839</strong>`,
'startDate': '2015/08/19',
'salary': 208.178
}, {
'name': 'Pearl Crosby',
'position': 'In PC',
'office': 'Cambodia',
'ext': `<strong>8262</strong>`,
'startDate': '2014/10/08',
'salary': 114.367
}, {
'name': 'Colette Foley',
'position': 'Lorem Inc.',
'office': 'Korea, North',
'ext': '8968',
'startDate': '2015/07/19',
'salary': 721.473
}, {
'name': 'Meghan Stephens',
'position': 'Interdum PC',
'office': 'Turkey',
'ext': '8001',
'startDate': '2014/10/11',
'salary': 469.305
}, {
'name': 'Bertha Herrera',
'position': 'Amet Limited',
'office': 'Kenya',
'ext': '4799',
'startDate': '2014/11/22',
'salary': 56.606
}, {
'name': 'Karina Key',
'position': 'Quisque Varius Nam Company',
'office': 'France',
'ext': '3907',
'startDate': '2015/03/26',
'salary': 314.260
}, {
'name': 'Uriel Carson',
'position': 'Penatibus PC',
'office': 'Venezuela',
'ext': '5902',
'startDate': '2015/01/07',
'salary': 106.335
}, {
'name': 'Mira Baird',
'position': 'Felis Orci PC',
'office': 'Niue',
'ext': '4189',
'startDate': '2015/08/25',
'salary': 515.671
}, {
'name': 'Ursula Parrish',
'position': 'Ac Corporation',
'office': 'Macao',
'ext': '4771',
'startDate': '2015/06/30',
'salary': 72.295
}, {
'name': 'Josephine Sykes',
'position': 'Blandit Congue Limited',
'office': 'Holy See (Vatican City State)',
'ext': '4684',
'startDate': '2014/12/22',
'salary': 694.656
}, {
'name': 'Maggie Sims',
'position': 'Vulputate Posuere Industries',
'office': 'Sudan',
'ext': '6482',
'startDate': '2014/11/22',
'salary': 363.743
}, {
'name': 'Rogan Fuentes',
'position': 'Vestibulum Accumsan Neque Company',
'office': 'Jersey',
'ext': '4837',
'startDate': '2015/07/29',
'salary': 606.004
}, {
'name': 'Maya Haney',
'position': 'Ac Foundation',
'office': 'Falkland Islands',
'ext': '5752',
'startDate': '2015/09/03',
'salary': 745.500
}, {
'name': 'Aquila Battle',
'position': 'Sociis Natoque Penatibus Foundation',
'office': 'Azerbaijan',
'ext': '8470',
'startDate': '2015/03/06',
'salary': 582.265
}, {
'name': 'Connor Coleman',
'position': 'Orci Lacus Vestibulum Foundation',
'office': 'Croatia',
'ext': '6217',
'startDate': '2014/10/21',
'salary': 416.958
}, {
'name': 'Charity Thomas',
'position': 'Convallis Ligula Donec Inc.',
'office': 'Benin',
'ext': '6240',
'startDate': '2015/07/12',
'salary': 540.999
}, {
'name': 'Blythe Powers',
'position': 'Amet Orci Limited',
'office': 'Falkland Islands',
'ext': '5608',
'startDate': '2015/01/23',
'salary': 480.067
}, {
'name': 'Adria Battle',
'position': 'Ornare Lectus Incorporated',
'office': 'British Indian Ocean Territory',
'ext': '7419',
'startDate': '2015/05/28',
'salary': 257.937
}, {
'name': 'Melanie Mcintyre',
'position': 'Nunc Corp.',
'office': 'Mongolia',
'ext': '4326',
'startDate': '2015/01/06',
'salary': 359.737
}, {
'name': 'Keely Bauer',
'position': 'Nec Tempus Institute',
'office': 'Somalia',
'ext': '8372',
'startDate': '2015/03/09',
'salary': 99.718
}, {
'name': 'Noelani Strong',
'position': 'Nec LLP',
'office': 'Iran',
'ext': '0049',
'startDate': '2015/08/24',
'salary': 480.718
}, {
'name': 'Jeanette Henderson',
'position': 'Eu Elit Nulla Corporation',
'office': 'Italy',
'ext': '7586',
'startDate': '2015/06/19',
'salary': 253.772
}, {
'name': 'Lionel Mcbride',
'position': 'Ipsum PC',
'office': 'Portugal',
'ext': '3978',
'startDate': '2015/07/11',
'salary': 34.244
}, {
'name': 'Paul Lucas',
'position': 'Eget LLP',
'office': 'Nicaragua',
'ext': '8890',
'startDate': '2014/09/30',
'salary': 690.834
}, {
'name': 'Lareina Williamson',
'position': 'Imperdiet Ullamcorper Ltd',
'office': 'Cocos (Keeling) Islands',
'ext': '9489',
'startDate': '2014/12/01',
'salary': 603.498
}, {
'name': 'Amy Acevedo',
'position': 'Id Institute',
'office': 'Cook Islands',
'ext': '5592',
'startDate': '2015/02/04',
'salary': 125.165
}, {
'name': 'Nomlanga Silva',
'position': 'Eget LLC',
'office': 'Belize',
'ext': '3110',
'startDate': '2015/01/31',
'salary': 268.509
}, {
'name': 'Amena Stone',
'position': 'Enim Incorporated',
'office': 'Guinea',
'ext': '1211',
'startDate': '2014/09/23',
'salary': 214.381
}, {
'name': 'Danielle Coffey',
'position': 'Feugiat Placerat Corp.',
'office': 'Sao Tome and Principe',
'ext': '8176',
'startDate': '2015/06/17',
'salary': 137.423
}, {
'name': 'Buffy Russell',
'position': 'Lacus Quisque Ltd',
'office': 'Ecuador',
'ext': '6741',
'startDate': '2014/10/17',
'salary': 612.184
}, {
'name': 'Kaitlin Lamb',
'position': 'Malesuada Fringilla Est Associates',
'office': 'Algeria',
'ext': '5054',
'startDate': '2014/10/18',
'salary': 327.367
}, {
'name': 'Leilani Yates',
'position': 'Mus Proin LLC',
'office': 'South Sudan',
'ext': '1550',
'startDate': '2015/05/27',
'salary': 743.493
}, {
'name': 'Jemima Moon',
'position': 'Phasellus Corp.',
'office': 'South Georgia and The South Sandwich Islands',
'ext': '7582',
'startDate': '2015/05/21',
'salary': 496.067
}, {
'name': 'Hiroko Schwartz',
'position': 'Neque Institute',
'office': 'Saint Vincent and The Grenadines',
'ext': '9368',
'startDate': '2015/03/13',
'salary': 178.782
}, {
'name': 'Nathaniel Jensen',
'position': 'Mi Tempor Limited',
'office': 'Dominica',
'ext': '8331',
'startDate': '2014/12/05',
'salary': 37.441
}, {
'name': 'Silas Sweeney',
'position': 'Ultrices Institute',
'office': 'Turkmenistan',
'ext': '0746',
'startDate': '2014/11/13',
'salary': 152.980
}, {
'name': 'Jermaine Barry',
'position': 'Dapibus Corporation',
'office': 'Uzbekistan',
'ext': '1545',
'startDate': '2015/03/06',
'salary': 409.463
}, {
'name': 'Tatiana Nichols',
'position': 'Nec Diam Industries',
'office': 'Cook Islands',
'ext': '4395',
'startDate': '2015/05/22',
'salary': 51.155
}, {
'name': 'Rama Waller',
'position': 'Sem Pellentesque LLC',
'office': 'Andorra',
'ext': '2973',
'startDate': '2014/12/01',
'salary': 223.227
}
];




Filter

The responsibility of the filtering issue falls on user. You should choose on which columns the filter would be applied. You could add any number of different filters. Filter string – it’s a string for matching values in raw data. Column name refers to the property name in raw data. The rest logic you could organize by yourself (the order of filters, data formats, etc). Even you could use filter for list of data columns.

You can also set up filtering param for columns, in this case filter box will appear in first row of the table.

Sorting

Data sorting could be in 3 modes: asc, desc and without sorting data (as it comes from backend or somewhere else). If you want to switch off the sorting for some of the columns then you should set it forcibly in columns config (set property sort to false value for each column you want)

Paging

Pagination could be used from ng2-bootstrap – pagination component. When the page is changed, the pagination component will emit event tableChanged with an object {page, itemsPerPage}. Then you can easily subscribe on it and request corresponding raw data.

Spread the Code

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of