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

391 lines
9.2 KiB
JavaScript

import ElCheckbox from 'element-ui/packages/checkbox';
import ElTag from 'element-ui/packages/tag';
import objectAssign from 'element-ui/src/utils/merge';
import { getPropByPath } from 'element-ui/src/utils/util';
let columnIdSeed = 1;
const defaults = {
default: {
order: ''
},
selection: {
width: 48,
minWidth: 48,
realWidth: 48,
order: '',
className: 'el-table-column--selection'
},
expand: {
width: 48,
minWidth: 48,
realWidth: 48,
order: ''
},
index: {
width: 48,
minWidth: 48,
realWidth: 48,
order: ''
}
};
const forced = {
selection: {
renderHeader: function(h) {
return <el-checkbox
nativeOn-click={ this.toggleAllSelection }
value={ this.isAllSelected } />;
},
renderCell: function(h, { row, column, store, $index }) {
return <el-checkbox
value={ store.isSelected(row) }
disabled={ column.selectable ? !column.selectable.call(null, row, $index) : false }
on-input={ () => { store.commit('rowSelectedChanged', row); } } />;
},
sortable: false,
resizable: false
},
index: {
renderHeader: function(h, { column }) {
return column.label || '#';
},
renderCell: function(h, { $index, column }) {
let i = $index + 1;
const index = column.index;
if (typeof index === 'number') {
i = $index + index;
} else if (typeof index === 'function') {
i = index($index);
}
return <div>{ i }</div>;
},
sortable: false
},
expand: {
renderHeader: function(h, { column }) {
return column.label || '';
},
renderCell: function(h, { row, store }, proxy) {
const expanded = store.states.expandRows.indexOf(row) > -1;
return <div class={ 'el-table__expand-icon ' + (expanded ? 'el-table__expand-icon--expanded' : '') }
on-click={ () => proxy.handleExpandClick(row) }>
<i class='el-icon el-icon-arrow-right'></i>
</div>;
},
sortable: false,
resizable: false,
className: 'el-table__expand-column'
}
};
const getDefaultColumn = function(type, options) {
const column = {};
objectAssign(column, defaults[type || 'default']);
for (let name in options) {
if (options.hasOwnProperty(name)) {
const value = options[name];
if (typeof value !== 'undefined') {
column[name] = value;
}
}
}
if (!column.minWidth) {
column.minWidth = 80;
}
column.realWidth = column.width || column.minWidth;
return column;
};
const DEFAULT_RENDER_CELL = function(h, { row, column }) {
const property = column.property;
const value = property && getPropByPath(row, property).v;
if (column && column.formatter) {
return column.formatter(row, column, value);
}
return value;
};
export default {
name: 'ElTableColumn',
props: {
type: {
type: String,
default: 'default'
},
label: String,
className: String,
labelClassName: String,
property: String,
prop: String,
width: {},
minWidth: {},
renderHeader: Function,
sortable: {
type: [String, Boolean],
default: false
},
sortMethod: Function,
sortBy: [String, Function, Array],
resizable: {
type: Boolean,
default: true
},
context: {},
columnKey: String,
align: String,
headerAlign: String,
showTooltipWhenOverflow: Boolean,
showOverflowTooltip: Boolean,
fixed: [Boolean, String],
formatter: Function,
selectable: Function,
reserveSelection: Boolean,
filterMethod: Function,
filteredValue: Array,
filters: Array,
filterPlacement: String,
filterMultiple: {
type: Boolean,
default: true
},
index: [Number, Function]
},
data() {
return {
isSubColumn: false,
columns: []
};
},
beforeCreate() {
this.row = {};
this.column = {};
this.$index = 0;
},
components: {
ElCheckbox,
ElTag
},
computed: {
owner() {
let parent = this.$parent;
while (parent && !parent.tableId) {
parent = parent.$parent;
}
return parent;
}
},
created() {
this.customRender = this.$options.render;
this.$options.render = h => h('div', this.$slots.default);
this.columnId = (this.$parent.tableId || (this.$parent.columnId + '_')) + 'column_' + columnIdSeed++;
let parent = this.$parent;
let owner = this.owner;
this.isSubColumn = owner !== parent;
let type = this.type;
let width = this.width;
if (width !== undefined) {
width = parseInt(width, 10);
if (isNaN(width)) {
width = null;
}
}
let minWidth = this.minWidth;
if (minWidth !== undefined) {
minWidth = parseInt(minWidth, 10);
if (isNaN(minWidth)) {
minWidth = 80;
}
}
let isColumnGroup = false;
let column = getDefaultColumn(type, {
id: this.columnId,
columnKey: this.columnKey,
label: this.label,
className: this.className,
labelClassName: this.labelClassName,
property: this.prop || this.property,
type,
renderCell: null,
renderHeader: this.renderHeader,
minWidth,
width,
isColumnGroup,
context: this.context,
align: this.align ? 'is-' + this.align : null,
headerAlign: this.headerAlign ? 'is-' + this.headerAlign : (this.align ? 'is-' + this.align : null),
sortable: this.sortable === '' ? true : this.sortable,
sortMethod: this.sortMethod,
sortBy: this.sortBy,
resizable: this.resizable,
showOverflowTooltip: this.showOverflowTooltip || this.showTooltipWhenOverflow,
formatter: this.formatter,
selectable: this.selectable,
reserveSelection: this.reserveSelection,
fixed: this.fixed === '' ? true : this.fixed,
filterMethod: this.filterMethod,
filters: this.filters,
filterable: this.filters || this.filterMethod,
filterMultiple: this.filterMultiple,
filterOpened: false,
filteredValue: this.filteredValue || [],
filterPlacement: this.filterPlacement || '',
index: this.index
});
objectAssign(column, forced[type] || {});
this.columnConfig = column;
let renderCell = column.renderCell;
let _self = this;
if (type === 'expand') {
owner.renderExpanded = function(h, data) {
return _self.$scopedSlots.default
? _self.$scopedSlots.default(data)
: _self.$slots.default;
};
column.renderCell = function(h, data) {
return <div class="cell">{ renderCell(h, data, this._renderProxy) }</div>;
};
return;
}
column.renderCell = function(h, data) {
if (_self.$scopedSlots.default) {
renderCell = () => _self.$scopedSlots.default(data);
}
if (!renderCell) {
renderCell = DEFAULT_RENDER_CELL;
}
return _self.showOverflowTooltip || _self.showTooltipWhenOverflow
? <div class="cell el-tooltip" style={'width:' + (data.column.realWidth || data.column.width) + 'px'}>{ renderCell(h, data) }</div>
: <div class="cell">{ renderCell(h, data) }</div>;
};
},
destroyed() {
if (!this.$parent) return;
this.owner.store.commit('removeColumn', this.columnConfig);
},
watch: {
label(newVal) {
if (this.columnConfig) {
this.columnConfig.label = newVal;
}
},
prop(newVal) {
if (this.columnConfig) {
this.columnConfig.property = newVal;
}
},
property(newVal) {
if (this.columnConfig) {
this.columnConfig.property = newVal;
}
},
filters(newVal) {
if (this.columnConfig) {
this.columnConfig.filters = newVal;
}
},
filterMultiple(newVal) {
if (this.columnConfig) {
this.columnConfig.filterMultiple = newVal;
}
},
align(newVal) {
if (this.columnConfig) {
this.columnConfig.align = newVal ? 'is-' + newVal : null;
if (!this.headerAlign) {
this.columnConfig.headerAlign = newVal ? 'is-' + newVal : null;
}
}
},
headerAlign(newVal) {
if (this.columnConfig) {
this.columnConfig.headerAlign = 'is-' + (newVal ? newVal : this.align);
}
},
width(newVal) {
if (this.columnConfig) {
this.columnConfig.width = newVal;
this.owner.store.scheduleLayout();
}
},
minWidth(newVal) {
if (this.columnConfig) {
this.columnConfig.minWidth = newVal;
this.owner.store.scheduleLayout();
}
},
fixed(newVal) {
if (this.columnConfig) {
this.columnConfig.fixed = newVal;
this.owner.store.scheduleLayout();
}
},
sortable(newVal) {
if (this.columnConfig) {
this.columnConfig.sortable = newVal;
}
},
index(newVal) {
if (this.columnConfig) {
this.columnConfig.index = newVal;
}
}
},
mounted() {
const owner = this.owner;
const parent = this.$parent;
let columnIndex;
if (!this.isSubColumn) {
columnIndex = [].indexOf.call(parent.$refs.hiddenColumns.children, this.$el);
} else {
columnIndex = [].indexOf.call(parent.$el.children, this.$el);
}
owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null);
}
};