import { LocaleService } from '@farris/ui-locale'; /* * @Author: 疯狂秀才(Lucas Huang) * @Date: 2019-08-14 13:53:03 * @LastEditors: 疯狂秀才(Lucas Huang) * @LastEditTime: 2019-10-01 15:02:29 * @QQ: 1055818239 * @Version: v0.0.1 */ import { Component, OnInit, Input, Output, Optional, ElementRef, Renderer2, AfterViewInit, EventEmitter, Directive, HostListener, SkipSelf, Injector, OnChanges, SimpleChanges } from '@angular/core'; import { convertColumns } from '../datatable-column'; import { DataTableService } from '../datatable.service'; import { DataTableComponent } from '../datatable.component'; import { ColumnFormatService, DataColumn } from '@farris/ui-common/column'; import { CommonUtils } from '@farris/ui-common'; @Directive({ selector: '[dblclick]' }) export class DTDblClickRowDirective implements OnInit { @Input('dblclick') row; constructor( public el: ElementRef, @Optional() public dt: DataTableComponent ) {} ngOnInit() {} @HostListener('dblclick', ['$event']) ondblclick(event: Event) { if (this.row) { this.dt.rowDblClick.emit(this.row); } event.stopPropagation(); } } @Component({ selector: 'datatable-body', template: `
`, styles: [ ` .table td:focus-within { box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.13); } .table td div { width: 100%; height: 100%; } .table td input { width: 100%; height: 100%; font-family: auto; line-height: 1; font-size: 13px; } .table td input:focus { border: 0; } input[type='checkbox']:focus { outline: none; } ` ] }) export class DataTableBodyComponent implements OnInit, AfterViewInit, OnChanges { @Input() size: string; @Input() hover: boolean; @Input() bordered: boolean; @Input() striped: boolean; @Input() columns: DataColumn[]; @Input() fixed: string; @Input() rows: any[] = []; @Input() rowClassName: (row: any, index: number) => string; @Input() cellClassName: (value: any, col: any) => string; @Output() rowDblClick = new EventEmitter(); @Output() selectRow: EventEmitter = new EventEmitter(); @Output() cellEdit: EventEmitter = new EventEmitter(); @Output() cellClick: EventEmitter = new EventEmitter(); lastRowIndex = 0; lastColumnIndex = 0; boxShadow: string; _rows: any; edit = {}; className = {}; isRowTempl = false; selectedRowIndex = -1; _selections = {}; emptyMessage = '暂无数据'; // 已选择的行 默认为空 set selections(v) { this._selections = v || {}; this.dt.updateCheckboxState(this.rows); } get selections(): any { if (!this._selections) { return; } const keys = Object.keys(this._selections); if (keys.length) { if (this.dt.singleSelect) { return this._selections; } else { return keys.map(k => this._selections[k]); } } return undefined; } private localeService: LocaleService; constructor( public el: ElementRef, private dataService: DataTableService, private render: Renderer2, @Optional() public dt: DataTableComponent, public colFormatSer: ColumnFormatService, public utils: CommonUtils, private injector: Injector ) { this.localeService = this.injector.get(LocaleService); } ngOnInit() { this.dataService.selectedAll.subscribe(allChecked => { const idfield = this.idField(); this.rows.forEach(row => { if (allChecked) { this._selections[row[idfield]] = row; } else { delete this._selections[row[idfield]]; } }); }); if (this.rows) { this.isRowTempl = this.rows.some(row => { return row.hasOwnProperty('rowTempl'); }); } if (this.fixed === 'left') { this.columns = convertColumns(this.columns, 'left'); } if (this.fixed === 'right') { this.columns = convertColumns(this.columns, 'right'); } this.emptyMessage = this.localeService.getValue('datagrid.emptyMessage'); } ngAfterViewInit() { this._rows = this.el.nativeElement.querySelectorAll('tr'); } ngOnChanges(changes: SimpleChanges) { if (changes.rows && !changes.rows.isFirstChange()) { if (!this.dt.singleSelect) { const checkedRows = changes.rows.currentValue.map(n => { return this.isSelected(n) ? 1 : 0; }).filter(n => n); if (!changes.rows.currentValue.length) { this.dataService.updateCheckAllStatus.next(0); return; } if (checkedRows.length === changes.rows.currentValue.length) { this.dataService.updateCheckAllStatus.next(1); } else { if (checkedRows.length === 0) { this.dataService.updateCheckAllStatus.next(0); } else { this.dataService.updateCheckAllStatus.next(2); } } } } } /** * 获取对象中指定字段的值。 field: 可以为带有层级结构的路径,如: user.firstName | name 等 */ getValue(field: string, data: any) { if (field.indexOf('.') === -1) { return data[field]; } else { return ( field.split('.').reduce((obj, key) => { return obj[key]; }, data) || '' ); } } selectedRow(event: any, index: number, data: any) { if (event) { event.stopPropagation(); event.preventDefault(); } let isSelected = false; const idfield = this.idField(); if (this.dt.singleSelect) { if (this.selectedRowIndex !== index || !this._selections || this._selections[idfield] !== data[idfield]) { this.selectedRowIndex = index; this._selections = data; isSelected = true; this.dataService.selectedRow.next({ rowIndex: index, rowData: data }); } else { if (!this.dt.keepSelect) { this.selectedRowIndex = -1; this._selections = undefined; isSelected = false; this.dataService.unSelectedRow.next({ rowIndex: index, rowData: data }); } else { isSelected = true; } } } else { if (this.isSelected(data)) { delete this._selections[data[idfield]]; isSelected = false; this.dataService.unSelectedRow.next({ rowIndex: index, rowData: data }); } else { this._selections[data[this.idField()]] = data; isSelected = true; this.dataService.selectedRow.next({ rowIndex: index, rowData: data }); } } if (isSelected) { this.dt.selectedRow.emit({ data, index }); // 兼容 this.dt.selectRows.emit({ data, index }); } else { this.dt.unSelectRow.emit({ data, index }); } } onChecked(event: any, index: number, data: any) { const state = event.checked; const idfield = this.dt.idField; if (state) { this._selections[data[idfield]] = data; this.dataService.selectedRow.next({ rowIndex: index, rowData: data }); this.dt.selectedRow.emit({ data, index }); // 兼容 this.dt.selectRows.emit({ data, index }); } else { delete this._selections[data[idfield]]; this.dataService.unSelectedRow.next({ rowIndex: index, rowData: data }); this.dt.unSelectRow.emit({ data, index }); } event.originalEvent.stopPropagation(); } private idField() { return this.dt.idField; } isSelected(row: any) { const idfield = this.idField(); if (this._selections) { if (this.dt.singleSelect) { return this._selections[idfield] === row[idfield]; } else { return this._selections[row[idfield]] !== undefined; } } return false; } formatData(field: any, data: any, formatter: any) { const value = this.utils.getValue(field, data, true); return this.colFormatSer.format(value, data, formatter); } // 添加自定义设置列 单元格类样式 getTdClassName(value, col) { const tempClassName = {}; // 列类的样式 if ( col.className && Object.prototype.toString.call(col.className) === '[object String]' ) { tempClassName[col.className] = true; } if (this.cellClassName && this.cellClassName(value, col)) { tempClassName[this.cellClassName(value, col)] = true; } return tempClassName; } createRowClassName(row, index) { return this.rowClassName ? this.rowClassName(row, index) : ''; } onCellClick(event: Event, col: any, row: any) { this.cellClick.emit({event, col, row}); } renderRowStyle(row, index) { if (this.dt.rowStyler) { return this.dt.rowStyler({ data: row, index }); } return ''; } renderCellStyle(val, row, index, col) { if (this.dt.cellStyler) { return this.dt.cellStyler({ value: val, data: row, index, col, field: col.field }); } return ''; } }