File

src/app/component/table/table.component.ts

Implements

OnInit

Metadata

selector stbui-table
styleUrls ./table.component.scss
templateUrl ./table.component.html

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(element: ElementRef, renderer: Renderer2)
Parameters :
Name Type Optional
element ElementRef No
renderer Renderer2 No

Inputs

border
Type : boolean
Default value : false
columns
Default value : []
data
Default value : []
disabledHover
Type : boolean
Default value : true
height
Type : string | number
highlightRow
Type : boolean
Default value : false
showHeader
Type : boolean
Default value : true
stripe
Type : boolean
Default value : false
tableSize
Type : string
Default value : 'default'
width
Type : string | number

Outputs

onCurrentChange
Type : EventEmitter
onRowClick
Type : EventEmitter
onSelect
Type : EventEmitter
onSelectAll
Type : EventEmitter
onSelectCancel
Type : EventEmitter
onSelectChange
Type : EventEmitter
onSortChange
Type : EventEmitter

Methods

fixedRightTableStyle
fixedRightTableStyle()
Returns : { width: string; }
isLeftFixed
isLeftFixed()
Returns : any
isRightFixed
isRightFixed()
Returns : any
leftFixedColumns
leftFixedColumns()
Returns : {}
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onCheckBoxAllTrigger
onCheckBoxAllTrigger($event)
Parameters :
Name Optional
$event No
Returns : void
onCheckBoxTrigger
onCheckBoxTrigger($event, row)
Parameters :
Name Optional
$event No
row No
Returns : void
onRowClickTrigger
onRowClickTrigger(row)
Parameters :
Name Optional
row No
Returns : void
rightFixedColumns
rightFixedColumns()
Returns : {}

Properties

_fixedTopCell
Type : ElementRef
Decorators :
@ViewChild('fixedTopCell', {static: false})
Private cells
Type : []
Default value : []
checkboxSelection
Type : []
Default value : []
checked
Type : boolean
Default value : false
cloneColumns
import { Component, OnInit } from '@angular/core';
import { Input, Output, EventEmitter } from '@angular/core';
import { ElementRef, ViewChild, Renderer2 } from '@angular/core';

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

  @Input() data = [];
  // 表格列的配置描述
  @Input() columns = [];
  // 是否显示间隔斑马纹
  @Input() stripe: boolean = false;
  // 是否显示纵向边框
  @Input() border: boolean = false;
  // 是否显示表头
  @Input() showHeader: boolean = true;
  // 表格宽度,单位 px
  @Input() width: string | number;
  // 表格高度,单位 px,设置后,如果表格内容大于此值,会固定表头
  @Input() height: string | number;
  // 禁用鼠标悬停时的高亮
  @Input() disabledHover: boolean = true;
  // 是否支持高亮选中的行,即单选
  @Input() highlightRow: boolean = false;
  @Input() tableSize: string = 'default';

  @Output() onCurrentChange = new EventEmitter();
  @Output() onSelect = new EventEmitter();
  @Output() onSelectCancel = new EventEmitter();
  @Output() onSelectAll = new EventEmitter();
  @Output() onSelectChange = new EventEmitter();
  @Output() onSortChange = new EventEmitter();
  @Output() onRowClick = new EventEmitter();

  cloneColumns;

  checkboxSelection = [];
  checked: boolean = false;

  @ViewChild('fixedTopCell', { static: false }) _fixedTopCell: ElementRef;
  private cells = [];

  constructor(private element: ElementRef, private renderer: Renderer2) {

  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    if (!this.height) return;
    const ths = this._fixedTopCell.nativeElement.children[0].children;

    setTimeout(() => {
      for (const th of ths) {
        this.cells.push({
          width: th.offsetWidth,
          height: th.offsetHeight
        });
      }
      this.border = true;
    });
  }

  fixedRightTableStyle() {
    let style = {};
    let width = 0;
    let rightFixedColumns = this.rightFixedColumns();
    rightFixedColumns.forEach((col) => {
      if (col.fixed && col.fixed === 'right') width += col._width;
    });
    // width += this.scrollBarWidth;
    return {
      width: `${width}px`
    };
  }

  leftFixedColumns() {
    let left = [];
    let other = [];
    this.cloneColumns.forEach((col) => {
      if (col.fixed && col.fixed === 'left') {
        left.push(col);
      } else {
        other.push(col);
      }
    });
    return left;
  }

  rightFixedColumns() {
    let right = [];
    let other = [];
    this.cloneColumns.forEach((col) => {
      if (col.fixed && col.fixed === 'right') {
        right.push(col);
      } else {
        other.push(col);
      }
    });
    return right;
  }

  isLeftFixed() {
    return this.columns.some(col => col.fixed && col.fixed === 'left');
  }

  isRightFixed() {
    return this.columns.some(col => col.fixed && col.fixed === 'right');
  }

  onRowClickTrigger(row) {
    this.onRowClick.emit(row);
  }

  onCheckBoxTrigger($event, row) {
    if ($event.checked) {
      this.checkboxSelection.push(row);
    } else {
      this.checkboxSelection = this.checkboxSelection.filter((source) => source !== row);
    }
    this.onSelectChange.emit(this.checkboxSelection);
  }

  onCheckBoxAllTrigger($event) {
    if ($event.checked) {
      this.checkboxSelection = this.data;
    } else {
      this.checkboxSelection = [];
    }

    this.onSelectAll.emit(this.checkboxSelection);
  }
}
<table class="table" [class.table-hover]="disabledHover" [class.table-striped]="stripe"
       [class.table-bordered]="border" *ngIf="!height">
  <thead>
  <tr>
    <th *ngFor="let column of columns">
      <div *ngIf="column.type === 'selection'">
        <mat-checkbox (change)="onCheckBoxAllTrigger($event)" [(ngModel)]="checked"></mat-checkbox>
      </div>
      <div *ngIf="column.type !== 'selection'">{{ column.title }}</div>
    </th>
  </tr>
  </thead>
  <tbody>
  <tr *ngFor="let row of data" (click)="onRowClickTrigger(row)">
    <td *ngFor="let column of columns">
      <div *ngIf="column.type === 'selection'">
        <mat-checkbox (change)="onCheckBoxTrigger($event, row)" [checked]="checked"></mat-checkbox>
      </div>
      <div *ngIf="column.type !== 'selection'">{{ row[column.key] }}</div>
    </td>
  </tr>
  </tbody>
</table>

<div class="fixed-table" [ngStyle]="{'height.px': height}" *ngIf="height">
  <div class="table-wrapper">
    <table class="table" [class.table-hover]="disabledHover" [class.table-striped]="stripe"
           [class.table-bordered]="border">
      <thead #fixedTopCell>
      <tr>
        <th *ngFor="let column of columns; let i= index">
          <div *ngIf="column.type === 'selection'">
            <mat-checkbox (change)="onCheckBoxAllTrigger($event)" [(ngModel)]="checked"></mat-checkbox>
          </div>
          {{ column?.title }}
          <div [ngStyle]="{'width.px':cells[i]?.width, 'height.px':cells[i]?.height}" class="fixed-table-heading"
               *ngIf="column.type !== 'selection'">{{ column.title }}
          </div>
        </th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let row of data" (click)="onRowClickTrigger(row)">
        <td *ngFor="let column of columns">
          <div *ngIf="column.type === 'selection'">
            <mat-checkbox (change)="onCheckBoxTrigger($event, row)" [checked]="checked"></mat-checkbox>
          </div>
          <div *ngIf="column.type !== 'selection'">{{ row[column.key] }}</div>
        </td>
      </tr>
      </tbody>
    </table>
  </div>
</div>

./table.component.scss

$table-header-font-weight: 400;
$table-header-font-color: #333;

$table-cell-padding: 16px;
$table-condensed-cell-padding: $table-cell-padding/2;

$table-bg: #fff;
$table-bg-accent: #f5f5f5;
$table-bg-hover: rgba(0, 0, 0, .12);
$table-bg-active: $table-bg-hover;
$table-border-color: #e0e0e0;
$table-grey-header-color: #FAFAFA;

.table {
  width: 100%;
  max-width: 100%;
  background-color: $table-bg;
  border-spacing: 0;
  > thead,
  > tbody,
  > tfoot {
    > tr {
      transition: all .3s ease;
      > th,
      > td {
        text-align: left;
        padding: $table-cell-padding;
        vertical-align: middle;
        border-top: 0;
        transition: all .3s ease;
      }
    }
  }
  > thead > tr > th {
    font-weight: $table-header-font-weight;
    color: $table-header-font-color;
    vertical-align: bottom;
    border-bottom: 1px solid rgba(0, 0, 0, .12);
  }
  > caption + thead,
  > colgroup + thead,
  > thead:first-child {
    > tr:first-child {
      > th,
      > td {
        border-top: 0;
      }
    }
  }
  > tbody + tbody {
    border-top: 1px solid rgba(0, 0, 0, .12);
  }

  .table {
    background-color: $table-bg;
  }

  .no-border {
    border: 0;
  }
}

.table-condensed {
  > thead,
  > tbody,
  > tfoot {
    > tr {
      > th,
      > td {
        padding: $table-condensed-cell-padding;
      }
    }
  }
}

.table-bordered {

  > thead > tr > th,
  > thead > tr > td {

    &:first-child {
      border-left: 0;
    }
  }

  > tbody > tr > td {
    border-bottom: 1px solid $table-border-color;
    border-left: 1px solid $table-border-color;
    border-top: none;

    &:first-child {
      border-left: 0;
    }
  }

}

.table-striped {
  > tbody > tr:nth-child(even) {
    > td,
    > th {
      background-color: $table-bg-accent;
    }
  }
}

.table-hover {
  > tbody > tr:hover {
    > td {
      background-color: $table-bg-hover;
    }
  }
}

.table-hover-cell {
  > tbody > tr > td:hover {
    background-color: $table-bg-hover;
  }
}

.table-striped.table-mc-red > tbody > tr:nth-child(odd) > td,
.table-striped.table-mc-red > tbody > tr:nth-child(odd) > th {
  background-color: #fde0dc;
}

.table-hover.table-mc-red > tbody > tr:hover > td,
.table-hover.table-mc-red > tbody > tr:hover > th {
  background-color: #f9bdbb;
}

@media screen and (max-width: 767px) {
  .table-responsive-vertical .table-striped.table-mc-red > tbody > tr > td,
  .table-responsive-vertical .table-striped.table-mc-red > tbody > tr:nth-child(odd) {
    background-color: $table-bg;
  }
  .table-responsive-vertical .table-striped.table-mc-red > tbody > tr > td:nth-child(odd) {
    background-color: #fde0dc;
  }
  .table-responsive-vertical .table-hover.table-mc-red > tbody > tr:hover > td,
  .table-responsive-vertical .table-hover.table-mc-red > tbody > tr:hover {
    background-color: $table-bg;
  }
  .table-responsive-vertical .table-hover.table-mc-red > tbody > tr > td:hover {
    background-color: #f9bdbb;
  }
}

.table-grey-header {
  thead {
    background-color: $table-grey-header-color;
  }
}

.fixed-table {
  position: relative;
  overflow: hidden;
  border: 1px solid $table-border-color;

  .table > thead > th {
    background: $table-grey-header-color;
    border-bottom: 1px solid $table-border-color;
    border-left: 1px solid transparent;
    border-top: none;
    color: rgba(0, 0, 0, 0);
  }
}

.table-wrapper {
  height: 100%;
  overflow: auto;
}

.fixed-table-heading {
  position: absolute;
  top: 0;
  padding: $table-cell-padding;
  background: $table-grey-header-color;
  border-bottom: 1px solid $table-border-color;
  border-left: 1px solid $table-border-color;
  border-top: none;
  color: $table-header-font-color;
  margin-left: -16px;
  z-index: 1;
  box-sizing: border-box;
}

Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""