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 '';
}
}