element/packages/table/src/table-body.js

278 lines
8.1 KiB
JavaScript
Raw Normal View History

import { getCell, getColumnByCell, getRowIdentity } from './util';
import { hasClass } from 'element-ui/src/utils/dom';
2016-12-09 03:49:30 +00:00
import ElCheckbox from 'element-ui/packages/checkbox';
import ElTooltip from 'element-ui/packages/tooltip';
import debounce from 'throttle-debounce/debounce';
2016-08-16 08:07:18 +00:00
export default {
2016-12-09 03:49:30 +00:00
components: {
ElCheckbox,
ElTooltip
2016-12-09 03:49:30 +00:00
},
2016-08-16 08:07:18 +00:00
props: {
store: {
required: true
},
2016-11-18 07:00:22 +00:00
context: {},
layout: {
required: true
},
rowClassName: [String, Function],
2016-11-24 16:14:23 +00:00
rowStyle: [Object, Function],
fixed: String,
highlight: Boolean
2016-08-16 08:07:18 +00:00
},
render(h) {
const columnsHidden = this.columns.map((column, index) => this.isColumnHidden(index));
2016-08-16 08:07:18 +00:00
return (
<table
class="el-table__body"
cellspacing="0"
cellpadding="0"
border="0">
<colgroup>
{
this._l(this.columns, column =>
<col
name={ column.id }
width={ column.realWidth || column.width }
/>)
}
</colgroup>
2016-08-16 08:07:18 +00:00
<tbody>
{
this._l(this.data, (row, $index) =>
2016-11-12 15:08:17 +00:00
[<tr
2016-11-24 16:14:23 +00:00
style={ this.rowStyle ? this.getRowStyle(row, $index) : null }
2016-12-23 04:00:01 +00:00
key={ this.table.rowKey ? this.getKeyOfRow(row, $index) : $index }
2016-12-02 09:11:04 +00:00
on-dblclick={ ($event) => this.handleDoubleClick($event, row) }
2016-08-16 08:07:18 +00:00
on-click={ ($event) => this.handleClick($event, row) }
on-contextmenu={ ($event) => this.handleContextMenu($event, row) }
2016-08-16 08:07:18 +00:00
on-mouseenter={ _ => this.handleMouseEnter($index) }
2016-11-03 13:00:09 +00:00
on-mouseleave={ _ => this.handleMouseLeave() }
class={ ['el-table__row', this.getRowClass(row, $index)] }>
2016-08-16 08:07:18 +00:00
{
this._l(this.columns, (column, cellIndex) =>
2016-08-16 08:07:18 +00:00
<td
class={ [column.id, column.align, column.className || '', columnsHidden[cellIndex] ? 'is-hidden' : '' ] }
2016-08-16 08:07:18 +00:00
on-mouseenter={ ($event) => this.handleCellMouseEnter($event, row) }
on-mouseleave={ this.handleCellMouseLeave }>
{
column.renderCell.call(this._renderProxy, h, { row, column, $index, store: this.store, _self: this.context || this.table.$vnode.context }, columnsHidden[cellIndex])
2016-08-16 08:07:18 +00:00
}
</td>
)
}
{
!this.fixed && this.layout.scrollY && this.layout.gutterWidth ? <td class="gutter" /> : ''
2016-08-16 08:07:18 +00:00
}
2016-11-12 15:08:17 +00:00
</tr>,
this.store.states.expandRows.indexOf(row) > -1
? (<tr>
<td colspan={ this.columns.length } class="el-table__expanded-cell">
{ this.table.renderExpanded ? this.table.renderExpanded(h, { row, $index, store: this.store }) : ''}
2016-11-12 15:08:17 +00:00
</td>
</tr>)
: ''
]
).concat(
this._self.$parent.$slots.append
).concat(
<el-tooltip effect={ this.table.tooltipEffect } placement="top" ref="tooltip" content={ this.tooltipContent }></el-tooltip>
2016-08-16 08:07:18 +00:00
)
}
</tbody>
</table>
);
},
watch: {
'store.states.hoverRow'(newVal, oldVal) {
if (!this.store.states.isComplex) return;
const el = this.$el;
if (!el) return;
const rows = el.querySelectorAll('tbody > tr');
const oldRow = rows[oldVal];
const newRow = rows[newVal];
if (oldRow) {
oldRow.classList.remove('hover-row');
}
if (newRow) {
newRow.classList.add('hover-row');
}
},
'store.states.currentRow'(newVal, oldVal) {
if (!this.highlight) return;
const el = this.$el;
if (!el) return;
const data = this.store.states.data;
const rows = el.querySelectorAll('tbody > tr.el-table__row');
const oldRow = rows[data.indexOf(oldVal)];
const newRow = rows[data.indexOf(newVal)];
if (oldRow) {
oldRow.classList.remove('current-row');
} else if (rows) {
[].forEach.call(rows, row => row.classList.remove('current-row'));
}
if (newRow) {
newRow.classList.add('current-row');
}
}
},
computed: {
2016-12-23 04:00:01 +00:00
table() {
return this.$parent;
2016-12-23 04:00:01 +00:00
},
data() {
return this.store.states.data;
},
columnsCount() {
return this.store.states.columns.length;
},
leftFixedCount() {
return this.store.states.fixedColumns.length;
},
rightFixedCount() {
return this.store.states.rightFixedColumns.length;
},
columns() {
return this.store.states.columns;
}
},
2016-08-16 08:07:18 +00:00
data() {
return {
tooltipContent: ''
2016-08-16 08:07:18 +00:00
};
},
created() {
this.activateTooltip = debounce(50, tooltip => tooltip.handleShowPopper());
},
2016-08-16 08:07:18 +00:00
methods: {
2016-11-12 18:57:08 +00:00
getKeyOfRow(row, index) {
2016-12-23 04:00:01 +00:00
const rowKey = this.table.rowKey;
2016-11-12 18:57:08 +00:00
if (rowKey) {
return getRowIdentity(row, rowKey);
}
return index;
},
isColumnHidden(index) {
if (this.fixed === true || this.fixed === 'left') {
return index >= this.leftFixedCount;
} else if (this.fixed === 'right') {
return index < this.columnsCount - this.rightFixedCount;
} else {
return (index < this.leftFixedCount) || (index >= this.columnsCount - this.rightFixedCount);
}
},
2016-11-24 16:14:23 +00:00
getRowStyle(row, index) {
const rowStyle = this.rowStyle;
if (typeof rowStyle === 'function') {
return rowStyle.call(null, row, index);
}
return rowStyle;
},
getRowClass(row, index) {
const classes = [];
const rowClassName = this.rowClassName;
if (typeof rowClassName === 'string') {
classes.push(rowClassName);
} else if (typeof rowClassName === 'function') {
2016-11-24 16:14:23 +00:00
classes.push(rowClassName.call(null, row, index) || '');
2016-08-26 06:01:14 +00:00
}
return classes.join(' ');
2016-08-26 06:01:14 +00:00
},
2016-08-16 08:07:18 +00:00
handleCellMouseEnter(event, row) {
2016-12-23 04:00:01 +00:00
const table = this.table;
2016-08-16 08:07:18 +00:00
const cell = getCell(event);
if (cell) {
const column = getColumnByCell(table, cell);
2016-11-12 15:08:17 +00:00
const hoverState = table.hoverState = {cell, column, row};
table.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event);
2016-08-16 08:07:18 +00:00
}
// 判断是否text-overflow, 如果是就显示tooltip
const cellChild = event.target.querySelector('.cell');
2016-08-16 08:07:18 +00:00
if (hasClass(cellChild, 'el-tooltip') && cellChild.scrollWidth > cellChild.offsetWidth) {
const tooltip = this.$refs.tooltip;
this.tooltipContent = cell.innerText;
tooltip.referenceElm = cell;
tooltip.$refs.popper.style.display = 'none';
tooltip.doDestroy();
tooltip.setExpectedState(true);
this.activateTooltip(tooltip);
}
2016-08-16 08:07:18 +00:00
},
handleCellMouseLeave(event) {
const tooltip = this.$refs.tooltip;
if (tooltip) {
tooltip.setExpectedState(false);
tooltip.handleClosePopper();
}
2016-08-16 08:07:18 +00:00
const cell = getCell(event);
if (!cell) return;
2016-08-16 08:07:18 +00:00
2016-12-23 04:00:01 +00:00
const oldHoverState = this.table.hoverState;
this.table.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event);
2016-08-16 08:07:18 +00:00
},
handleMouseEnter(index) {
this.store.commit('setHoverRow', index);
2016-08-16 08:07:18 +00:00
},
2016-11-03 13:00:09 +00:00
handleMouseLeave() {
this.store.commit('setHoverRow', null);
},
handleContextMenu(event, row) {
2017-03-06 10:45:27 +00:00
this.handleEvent(event, row, 'contextmenu');
},
2016-12-02 09:11:04 +00:00
handleDoubleClick(event, row) {
2017-03-06 10:45:27 +00:00
this.handleEvent(event, row, 'dblclick');
2016-12-02 09:11:04 +00:00
},
2016-08-16 08:07:18 +00:00
handleClick(event, row) {
2017-03-06 10:45:27 +00:00
this.store.commit('setCurrentRow', row);
this.handleEvent(event, row, 'click');
},
handleEvent(event, row, name) {
2016-12-23 04:00:01 +00:00
const table = this.table;
2016-08-16 08:07:18 +00:00
const cell = getCell(event);
let column;
2016-08-16 08:07:18 +00:00
if (cell) {
column = getColumnByCell(table, cell);
2016-08-16 08:07:18 +00:00
if (column) {
2017-03-06 10:45:27 +00:00
table.$emit(`cell-${name}`, row, column, cell, event);
2016-08-16 08:07:18 +00:00
}
}
2017-03-06 10:45:27 +00:00
table.$emit(`row-${name}`, row, event, column);
2016-11-12 15:08:17 +00:00
},
handleExpandClick(row) {
this.store.commit('toggleRowExpanded', row);
2016-08-16 08:07:18 +00:00
}
}
};