Skip to content

Commit

Permalink
Release 1.2.0 (#303)
Browse files Browse the repository at this point in the history
* add filter row to the table to filter data by column

* update dependency version, use @angular/forms, fix gulp task

* Added click on a row event

* update dependencies

* remove typings install from travis

* remove comments

* inc version

* custom css class to the table
  • Loading branch information
otelnov authored and valorkin committed Oct 5, 2016
1 parent 9077a57 commit 809da05
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 78 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -5,7 +5,6 @@ node_js:
before_install: npm i -g npm@latest

script:
- npm run flow.install:typings
- npm test

after_success:
Expand Down
72 changes: 59 additions & 13 deletions components/table/ng-table.component.ts
@@ -1,38 +1,68 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Component({
selector: 'ng-table',
template: `
<table class="table table-striped table-bordered dataTable"
<table class="table dataTable" ngClass="{{config.className || ''}}"
role="grid" style="width: 100%;">
<thead>
<tr role="row">
<th *ngFor="let column of columns" [ngTableSorting]="config" [column]="column" (sortChanged)="onChangeTable($event)">
{{column.title}}
<i *ngIf="config && column.sort" class="pull-right fa"
[ngClass]="{'fa-chevron-down': column.sort === 'desc', 'fa-chevron-up': column.sort === 'asc'}"></i>
</th>
</tr>
<tr role="row">
<th *ngFor="let column of columns" [ngTableSorting]="config" [column]="column"
(sortChanged)="onChangeTable($event)" ngClass="{{column.className || ''}}">
{{column.title}}
<i *ngIf="config && column.sort" class="pull-right fa"
[ngClass]="{'fa-chevron-down': column.sort === 'desc', 'fa-chevron-up': column.sort === 'asc'}"></i>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of rows">
<td *ngFor="let column of columns">{{getData(row, column.name)}}</td>
<tr *ngIf="showFilterRow">
<td *ngFor="let column of columns">
<input *ngIf="column.filtering" placeholder="{{column.filtering.placeholder}}"
[ngTableFiltering]="column.filtering"
class="form-control"
style="width: auto;"
(tableChanged)="onChangeTable(config)"/>
</td>
</tr>
<tr *ngFor="let row of rows">
<td (click)="cellClick(row, column.name)" *ngFor="let column of columns" [innerHtml]="sanitize(getData(row, column.name))"></td>
</tr>
</tbody>
</table>
`
})
export class NgTableComponent {
// Table values
@Input() public rows:Array<any> = [];
@Input() public config:any = {};

@Input()
public set config(conf:any) {
if (!conf.className) {
conf.className = 'table-striped table-bordered';
}
if (conf.className instanceof Array) {
conf.className = conf.className.join(' ');
}
this._config = conf;
}

// Outputs (Events)
@Output() public tableChanged:EventEmitter<any> = new EventEmitter();
@Output() public cellClicked:EventEmitter<any> = new EventEmitter();

public showFilterRow:Boolean = false;

@Input()
public set columns(values:Array<any>) {
values.forEach((value:any) => {
if (value.filtering) {
this.showFilterRow = true;
}
if (value.className && value.className instanceof Array) {
value.className = value.className.join(' ');
}
let column = this._columns.find((col:any) => col.name === value.name);
if (column) {
Object.assign(column, value);
Expand All @@ -43,10 +73,24 @@ export class NgTableComponent {
});
}

private _columns:Array<any> = [];
private _config:any = {};

public constructor(private sanitizer:DomSanitizer) {
}

public sanitize(html:string):SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(html);
}

public get columns():Array<any> {
return this._columns;
}

public get config():any {
return this._config;
}

public get configColumns():any {
let sortColumns:Array<any> = [];

Expand All @@ -59,8 +103,6 @@ export class NgTableComponent {
return {columns: sortColumns};
}

private _columns:Array<any> = [];

public onChangeTable(column:any):void {
this._columns.forEach((col:any) => {
if (col.name !== column.name && col.sort !== false) {
Expand All @@ -73,4 +115,8 @@ export class NgTableComponent {
public getData(row:any, propertyName:string):string {
return propertyName.split('.').reduce((prev:any, curr:string) => prev[curr], row);
}

public cellClick(row:any, column:any):void {
this.cellClicked.emit({row, column});
}
}
12 changes: 10 additions & 2 deletions components/table/readme.md
Expand Up @@ -6,7 +6,7 @@ or if you want to import specified plugins (Table component is required, the oth
```typescript
import { NgTableComponent, NgTableFilteringDirective, NgTablePagingDirective, NgTableSortingDirective } from 'ng2-table/ng2-table';
```
in this case, don't forget to include all of the imported entities to the option `directives` in your component
in this case, don't forget to include all of the imported entities to your module

### Utilisation

Expand All @@ -27,22 +27,30 @@ There are only simple table with 3 plugins/directives: `filtering`, `paging`, `s
- `filtering` (`?any`) - switch on the filtering plugin
- `filterString` (`string`) - the default value for filter
- `columnName` (`string`) - the property name in raw data
- `className` (`string|Array<string>`) - additional CSS classes that should be added to a <table>

- `rows` (`?Array<any>`) - only list of the rows which should be displayed
- `columns` (`?Array<any>`) - config for columns (+ sorting settings if it's needed)
- `title` (`string`) - the title of column header
- `name` (`string`) - the property name in data
- `sort` (`?string|boolean`) - config for columns (+ sorting settings if it's needed), sorting is switched on by default for each column
- `className` (`string|Array<string>`) - additional CSS classes that should be added to a column header
- `filtering` (`?any`) - switch on the filtering plugin
- `filterString` (`string`) - the default value for filter
- `columnName` (`string`) - the property name in raw data

### Outputs (Events)

- `tableChanged`: onclick event handler
- `tableChanged`: data change event handler
- `cellClicked`: onclick event handler

### 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)
Expand Down
4 changes: 2 additions & 2 deletions demo/components/table/table-data.ts
Expand Up @@ -3,14 +3,14 @@ export const TableData:Array<any> = [
'name': 'Victoria Cantrell',
'position': 'Integer Corporation',
'office': 'Croatia',
'ext': '0839',
'ext': `<strong>0839</strong>`,
'startDate': '2015/08/19',
'salary': 208.178
}, {
'name': 'Pearl Crosby',
'position': 'In PC',
'office': 'Cambodia',
'ext': '8262',
'ext': `<strong>8262</strong>`,
'startDate': '2014/10/08',
'salary': 114.367
}, {
Expand Down
16 changes: 11 additions & 5 deletions demo/components/table/table-demo.html
@@ -1,9 +1,15 @@
<input *ngIf="config.filtering" placeholder="Filter"
[ngTableFiltering]="config.filtering"
(tableChanged)="onChangeTable(config)"/>

<ng-table [config]="config.sorting"
<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>
<br>
<ng-table [config]="config"
(tableChanged)="onChangeTable(config)"
(cellClicked)="onCellClick($event)"
[rows]="rows" [columns]="columns">
</ng-table>
<pagination *ngIf="config.paging"
Expand Down
55 changes: 45 additions & 10 deletions demo/components/table/table-demo.ts
Expand Up @@ -11,11 +11,16 @@ let template = require('./table-demo.html');
export class TableDemoComponent implements OnInit {
public rows:Array<any> = [];
public columns:Array<any> = [
{title: 'Name', name: 'name'},
{title: 'Position', name: 'position', sort: false},
{title: 'Office', name: 'office', sort: 'asc'},
{title: 'Extn.', name: 'ext', sort: ''},
{title: 'Start date', name: 'startDate'},
{title: 'Name', name: 'name', filtering: {filterString: '', placeholder: 'Filter by name'}},
{
title: 'Position',
name: 'position',
sort: false,
filtering: {filterString: '', placeholder: 'Filter by position'}
},
{title: 'Office', className: ['office-header', 'text-success'], name: 'office', sort: 'asc'},
{title: 'Extn.', name: 'ext', sort: '', filtering: {filterString: '', placeholder: 'Filter by extn.'}},
{title: 'Start date', className: 'text-warning', name: 'startDate'},
{title: 'Salary ($)', name: 'salary'}
];
public page:number = 1;
Expand All @@ -27,7 +32,8 @@ export class TableDemoComponent implements OnInit {
public config:any = {
paging: true,
sorting: {columns: this.columns},
filtering: {filterString: '', columnName: 'position'}
filtering: {filterString: ''},
className: ['table-striped', 'table-bordered']
};

private data:Array<any> = TableData;
Expand All @@ -41,7 +47,6 @@ export class TableDemoComponent implements OnInit {
}

public changePage(page:any, data:Array<any> = this.data):Array<any> {
console.log(page);
let start = (page.page - 1) * page.itemsPerPage;
let end = page.itemsPerPage > -1 ? (start + page.itemsPerPage) : data.length;
return data.slice(start, end);
Expand Down Expand Up @@ -79,12 +84,37 @@ export class TableDemoComponent implements OnInit {
}

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 data;
return filteredData;
}

let filteredData:Array<any> = data.filter((item:any) =>
item[config.filtering.columnName].match(this.config.filtering.filterString));
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;
}
Expand All @@ -93,6 +123,7 @@ export class TableDemoComponent implements OnInit {
if (config.filtering) {
Object.assign(this.config.filtering, config.filtering);
}

if (config.sorting) {
Object.assign(this.config.sorting, config.sorting);
}
Expand All @@ -102,4 +133,8 @@ export class TableDemoComponent implements OnInit {
this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;
this.length = sortedData.length;
}

public onCellClick(data: any): any {
console.log(data);
}
}
5 changes: 5 additions & 0 deletions demo/index.ts
@@ -1,4 +1,9 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';

if (ENV === 'production') {
enableProdMode();
}

import { Ng2TableDemoModule } from './demo.module';
platformBrowserDynamic().bootstrapModule(Ng2TableDemoModule);

0 comments on commit 809da05

Please sign in to comment.