import { Component , EventEmitter , Input , Output } from '@angular/core' ; import { DomSanitizer , SafeHtml } from '@angular/platform-browser' ; @ Component ( { selector : 'ng-table' , template : `
    <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)" 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 *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 { @ Input ( ) public rows : Array < any > = [ ] ; @ Input ( ) public set config ( conf ) { if ( ! conf . className ) { conf . className = 'table-striped table-bordered' ; } if ( conf . className instanceof Array ) { conf . className = conf . className . join ( ' ' ) ; } this . _config = conf ; } @ Output ( ) public tableChanged : EventEmitter < any > = new EventEmitter ( ) ; @ Output ( ) public cellClicked : EventEmitter < any > = new EventEmitter ( ) ; public showFilterRow : Boolean = false ; @ Input ( ) public set columns ( values ) { values . forEach ( ( value ) => { if ( value . filtering ) { this . showFilterRow = true ; } if ( value . className && value . className instanceof Array ) { value . className = value . className . join ( ' ' ) ; } let column = this . _columns . find ( ( col ) => col . name === value . name ) ; if ( column ) { Object . assign ( column , value ) ; } if ( ! column ) { this . _columns . push ( value ) ; } } ) ; } private _columns : Array < any > = [ ] ; private _config : any = { } ; public constructor ( private sanitizer ) { } public sanitize ( html ) { 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 = [ ] ; this . columns . forEach ( ( column ) => { if ( column . sort ) { sortColumns . push ( column ) ; } } ) ; return { columns : sortColumns } ; } public onChangeTable ( column ) { this . _columns . forEach ( ( col ) => { if ( col . name !== column . name && col . sort !== false ) { col . sort = '' ; } } ) ; this . tableChanged . emit ( { sorting : this . configColumns } ) ; } public getData ( row , propertyName ) { return propertyName . split ( '.' ) . reduce ( ( prev , curr ) => prev [ curr ] , row ) ; } public cellClick ( row , column ) { this . cellClicked . emit ( { row , column } ) ; } }