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

314 lines
8.9 KiB
JavaScript
Raw Normal View History

2016-10-25 13:35:41 +00:00
import ElCheckbox from 'element-ui/packages/checkbox';
import ElTag from 'element-ui/packages/tag';
2016-10-27 13:45:21 +00:00
import Vue from 'vue';
import FilterPanel from './filter-panel.vue';
2016-08-16 08:07:18 +00:00
export default {
name: 'el-table-header',
render(h) {
return (
<table
class="el-table__header"
cellspacing="0"
cellpadding="0"
border="0">
{
this._l(this.columns, column =>
<col
2016-08-16 08:07:18 +00:00
name={ column.id }
width={ column.realWidth || column.width }
/>)
}
{
!this.fixed && this.layout.gutterWidth
? <col name="gutter" width={ this.layout.scrollY ? this.layout.gutterWidth : '' }></col>
: ''
}
<thead>
<tr>
{
this._l(this.columns, (column, cellIndex) =>
<th
on-mousemove={ ($event) => this.handleMouseMove($event, column) }
on-mouseout={ this.handleMouseOut }
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
on-click={ ($event) => this.handleClick($event, column) }
class={ [column.id, column.order, column.align, column.className || '', this.isCellHidden(cellIndex) ? 'is-hidden' : ''] }>
2016-10-27 13:45:21 +00:00
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : ''] }>
2016-08-16 08:07:18 +00:00
{
2016-11-04 23:30:23 +00:00
column.renderHeader
? column.renderHeader.call(this._renderProxy, h, { column, $index: cellIndex, store: this.store, _self: this.$parent.$vnode.context })
2016-10-27 13:45:21 +00:00
: column.label
2016-08-16 08:07:18 +00:00
}
2016-10-27 13:45:21 +00:00
{
column.sortable
? <span class="caret-wrapper" on-click={ ($event) => this.handleHeaderClick($event, column) }>
<i class="sort-caret ascending"></i>
<i class="sort-caret descending"></i>
</span>
: ''
}
{
column.filterable
? <span class="el-table__column-filter-trigger" on-click={ ($event) => this.handleFilterClick($event, column) }><i class={ ['el-icon-arrow-down', column.filterOpened ? 'el-icon-arrow-up' : ''] }></i></span>
: ''
}
</div>
</th>
)
}
{
!this.fixed && this.layout.gutterWidth
? <th class="gutter" style={{ width: this.layout.scrollY ? this.layout.gutterWidth + 'px' : '0' }}></th>
: ''
}
</tr>
</thead>
2016-08-16 08:07:18 +00:00
</table>
);
},
props: {
fixed: String,
store: {
required: true
},
layout: {
required: true
2016-08-16 08:07:18 +00:00
},
border: Boolean
},
components: {
ElCheckbox,
ElTag
},
computed: {
isAllSelected() {
return this.store.states.isAllSelected;
},
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-10-27 13:45:21 +00:00
created() {
this.filterPanels = {};
},
beforeDestroy() {
const panels = this.filterPanels;
for (let prop in panels) {
if (panels.hasOwnProperty(prop) && panels[prop]) {
panels[prop].$destroy(true);
}
}
},
2016-08-16 08:07:18 +00:00
methods: {
isCellHidden(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);
}
},
toggleAllSelection() {
this.store.commit('toggleAllSelection');
2016-08-16 08:07:18 +00:00
},
2016-10-27 13:45:21 +00:00
handleFilterClick(event, column) {
event.stopPropagation();
const target = event.target;
const cell = target.parentNode;
const table = this.$parent;
let filterPanel = this.filterPanels[column.id];
if (filterPanel && column.filterOpened) {
filterPanel.showPopper = false;
return;
}
if (!filterPanel) {
filterPanel = new Vue(FilterPanel);
this.filterPanels[column.id] = filterPanel;
filterPanel.table = table;
filterPanel.cell = cell;
filterPanel.column = column;
filterPanel.$mount(document.createElement('div'));
}
setTimeout(() => {
filterPanel.showPopper = true;
}, 16);
},
handleClick(event, column) {
this.$parent.$emit('header-click', column, event);
},
2016-08-16 08:07:18 +00:00
handleMouseDown(event, column) {
2016-10-27 15:25:03 +00:00
/* istanbul ignore if */
2016-08-16 08:07:18 +00:00
if (this.draggingColumn && this.border) {
this.dragging = true;
this.$parent.resizeProxyVisible = true;
const tableEl = this.$parent.$el;
const tableLeft = tableEl.getBoundingClientRect().left;
2016-08-16 08:07:18 +00:00
const columnEl = this.$el.querySelector(`th.${column.id}`);
const columnRect = columnEl.getBoundingClientRect();
const minLeft = columnRect.left - tableLeft + 30;
2016-08-16 08:07:18 +00:00
columnEl.classList.add('noclick');
this.dragState = {
startMouseLeft: event.clientX,
startLeft: columnRect.right - tableLeft,
startColumnLeft: columnRect.left - tableLeft,
tableLeft
2016-08-16 08:07:18 +00:00
};
const resizeProxy = this.$parent.$refs.resizeProxy;
resizeProxy.style.left = this.dragState.startLeft + 'px';
document.onselectstart = function() { return false; };
document.ondragstart = function() { return false; };
const handleMouseMove = (event) => {
2016-08-16 08:07:18 +00:00
const deltaLeft = event.clientX - this.dragState.startMouseLeft;
const proxyLeft = this.dragState.startLeft + deltaLeft;
resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px';
};
const handleMouseUp = () => {
2016-08-16 08:07:18 +00:00
if (this.dragging) {
const finalLeft = parseInt(resizeProxy.style.left, 10);
const columnWidth = finalLeft - this.dragState.startColumnLeft;
column.width = column.realWidth = columnWidth;
this.store.scheduleLayout();
2016-08-16 08:07:18 +00:00
document.body.style.cursor = '';
this.dragging = false;
this.draggingColumn = null;
this.dragState = {};
this.$parent.resizeProxyVisible = false;
}
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
2016-08-16 08:07:18 +00:00
document.onselectstart = null;
document.ondragstart = null;
setTimeout(function() {
columnEl.classList.remove('noclick');
}, 0);
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
2016-08-16 08:07:18 +00:00
}
},
handleMouseMove(event, column) {
2016-10-27 13:45:21 +00:00
let target = event.target;
while (target && target.tagName !== 'TH') {
target = target.parentNode;
}
2016-08-16 08:07:18 +00:00
if (!column || !column.resizable) return;
if (!this.dragging && this.border) {
let rect = target.getBoundingClientRect();
const bodyStyle = document.body.style;
2016-08-16 08:07:18 +00:00
if (rect.width > 12 && rect.right - event.pageX < 8) {
bodyStyle.cursor = 'col-resize';
2016-08-16 08:07:18 +00:00
this.draggingColumn = column;
} else if (!this.dragging) {
bodyStyle.cursor = '';
2016-08-16 08:07:18 +00:00
this.draggingColumn = null;
}
}
},
handleMouseOut() {
document.body.style.cursor = '';
},
handleHeaderClick(event, column) {
let target = event.target;
while (target && target.tagName !== 'TH') {
target = target.parentNode;
}
if (target && target.tagName === 'TH') {
if (target.classList.contains('noclick')) {
target.classList.remove('noclick');
return;
}
}
if (!column.sortable) return;
2016-10-27 17:24:13 +00:00
const states = this.store.states;
let sortProp = states.sortProp;
let sortOrder;
const sortingColumn = states.sortingColumn;
2016-08-16 08:07:18 +00:00
2016-10-27 17:24:13 +00:00
if (sortingColumn !== column) {
if (sortingColumn) {
sortingColumn.order = null;
2016-08-16 08:07:18 +00:00
}
2016-10-27 17:24:13 +00:00
states.sortingColumn = column;
sortProp = column.property;
2016-08-16 08:07:18 +00:00
}
2016-10-27 17:24:13 +00:00
if (!column.order) {
sortOrder = column.order = 'ascending';
} else if (column.order === 'ascending') {
sortOrder = column.order = 'descending';
2016-08-16 08:07:18 +00:00
} else {
2016-10-27 17:24:13 +00:00
sortOrder = column.order = null;
states.sortingColumn = null;
sortProp = null;
2016-08-16 08:07:18 +00:00
}
2016-10-27 17:24:13 +00:00
states.sortProp = sortProp;
states.sortOrder = sortOrder;
2016-08-16 08:07:18 +00:00
this.store.commit('changeSortCondition');
2016-08-16 08:07:18 +00:00
}
},
data() {
return {
draggingColumn: null,
dragging: false,
dragState: {}
2016-08-16 08:07:18 +00:00
};
}
};