UNPKG

vue-easytable

Version:
665 lines (592 loc) 20.7 kB
import HeaderCheckboxContent from "./header-checkbox-content"; import HeaderFilterContent from "./header-filter-content"; import HeaderFilterCustomContent from "./header-filter-custom-content"; import { getFixedTotalWidthByColumnKey, clsName, getColKeysByRangeColKeys, getColKeysByHeaderColumn, } from "../util"; import { getValByUnit, isEmptyValue } from "../../../src/utils/index.js"; import { COMPS_NAME, COLUMN_TYPES, EMIT_EVENTS } from "../util/constant"; import emitter from "../../../src/mixins/emitter"; import VeIcon from "vue-easytable/packages/ve-icon"; import { ICON_NAMES } from "../../../src/utils/constant"; export default { name: COMPS_NAME.VE_TABLE_THADER_Th, mixins: [emitter], props: { // group columns item groupColumn: { type: Array, required: true, }, // group column item groupColumnItem: { type: Object, required: true, }, colgroups: { type: Array, required: true, }, headerRows: { type: Array, default: function () { return []; }, }, fixedHeader: { type: Boolean, }, isGroupHeader: { type: Boolean, required: true, }, rowIndex: { type: Number, required: true, }, cellSelectionData: { type: Object, default: function () { return null; }, }, // cell selection range data cellSelectionRangeData: { type: Object, default: function () { return null; }, }, headerIndicatorColKeys: { type: Object, default: function () { return null; }, }, // checkbox option checkboxOption: { type: Object, default: function () { return null; }, }, // sort option sortOption: { type: Object, default: function () { return null; }, }, // sort columns sortColumns: { type: Object, default: function () { return null; }, }, // cell style option cellStyleOption: { type: Object, default: function () { return null; }, }, // event custom option eventCustomOption: { type: Object, default: function () { return null; }, }, }, computed: { // is last left fixed column isLastLeftFixedColumn() { let result = false; const { groupColumn, groupColumnItem: column } = this; const { fixed, _keys } = column; if (fixed === "left") { const leftFixedColumns = groupColumn.filter( (x) => x.fixed === "left", ); const index = leftFixedColumns.findIndex( (x) => x._keys === _keys, ); if (index === leftFixedColumns.length - 1) { result = true; } } return result; }, // is first right fixed column isfirstRightFixedColumn() { let result = false; const { groupColumn, groupColumnItem: column } = this; const { fixed, _keys } = column; if (fixed === "right") { const leftFixedColumns = groupColumn.filter( (x) => x.fixed === "right", ); if (leftFixedColumns[0]._keys === _keys) { result = true; } } return result; }, // is last column isLastCloumn() { let result = false; const { colgroups, groupColumnItem: column } = this; const lastColumnKey = colgroups[colgroups.length - 1].key; const keys = column._keys.split("|"); if (keys.length) { if (keys.length === 1) { if (keys[0] === lastColumnKey) { result = true; } } else if (keys[keys.length - 2] === lastColumnKey) { result = true; } } return result; }, // is sortable column isSortableCloumn() { let result = false; const { sortColumns, groupColumnItem } = this; const currentField = groupColumnItem.field; if (Object.keys(sortColumns).includes(currentField)) { result = true; } return result; }, }, methods: { /* * @getTheadThClass * @desc get thead th class * @param {string} fixed - 固定方式 */ getTheadThClass({ fixed }) { let result = { [clsName("header-th")]: true, [clsName("fixed-left")]: fixed === "left", [clsName("fixed-right")]: fixed === "right", [clsName("last-left-fixed-column")]: this.isLastLeftFixedColumn, [clsName("first-right-fixed-column")]: this.isfirstRightFixedColumn, [clsName("last-column")]: this.isLastCloumn, [clsName("sortable-column")]: this.isSortableCloumn, }; const { cellStyleOption, rowIndex, groupColumnItem: column, cellSelectionRangeData, colgroups, isGroupHeader, headerIndicatorColKeys, } = this; if (cellSelectionRangeData) { const { leftColKey, rightColKey } = cellSelectionRangeData; const { startColKeyIndex } = headerIndicatorColKeys; const isIndicatorActive = startColKeyIndex > -1; if (!isEmptyValue(leftColKey)) { let indicatorColKeys = []; if (leftColKey === rightColKey) { indicatorColKeys = [leftColKey]; } else { indicatorColKeys = getColKeysByRangeColKeys({ colKey1: leftColKey, colKey2: rightColKey, colgroups, }) ?? []; } let showIndicator = false; if (!isGroupHeader) { if (indicatorColKeys.indexOf(column["key"]) > -1) { showIndicator = true; } } else { const colKeys = getColKeysByHeaderColumn({ headerColumnItem: column, }); showIndicator = colKeys.every((colKey) => { return indicatorColKeys.indexOf(colKey) > -1; }); } if (showIndicator) { if (isIndicatorActive) { result[clsName("cell-indicator-active")] = true; } else { result[clsName("cell-indicator")] = true; } } } } if ( cellStyleOption && typeof cellStyleOption.headerCellClass === "function" ) { const customClass = cellStyleOption.headerCellClass({ column, rowIndex, }); if (customClass) { result[customClass] = true; } } return result; }, /* * @getTheadThStyle * @desc get body td style * @param {string} _keys - 当前列包含的key(单元格合并时有多个key值) * @param {string} align - 居中方式 * @param {bool} fixed - 固定方式 * @param {number} rowIndex - 当前行号 */ getTheadThStyle({ _keys, align, fixed }, rowIndex) { let result = {}; const colgroups = this.colgroups; const headerRows = this.headerRows; // text align result["text-align"] = align || "center"; // fixed left total width or right total width if (fixed) { let key = ""; let totalWidth = 0; const keys = _keys.split("|"); if (fixed === "left") { key = keys[0]; } else if (fixed === "right") { key = keys.length === 1 ? keys[0] : keys[keys.length - 2]; } if (key) { // column index const columnIndex = colgroups.findIndex( (x) => x.key === key, ); if ( (fixed === "left" && columnIndex > 0) || (fixed === "right" && columnIndex < colgroups.length - 1) ) { totalWidth = getFixedTotalWidthByColumnKey({ colgroups, colKey: key, fixed, }); totalWidth = getValByUnit(totalWidth); } } result["left"] = fixed === "left" ? totalWidth : ""; result["right"] = fixed === "right" ? totalWidth : ""; } // header row th fixed top if (this.fixedHeader) { let rowHeight = 0; if (rowIndex > 0) { rowHeight = headerRows.reduce( (total, currentVal, index) => { return index < rowIndex ? currentVal.rowHeight + total : total; }, 0, ); } rowHeight = getValByUnit(rowHeight); result["top"] = rowHeight; } return result; }, // get chcekbox content getCheckboxContent() { let result = null; const { checkboxOption } = this; if (this.groupColumnItem.type === COLUMN_TYPES.CHECKBOX) { if (!checkboxOption.hideSelectAll) { // checkbox content props const checkboxProps = { props: { column: this.groupColumnItem, checkboxOption: this.checkboxOption, }, }; result = <HeaderCheckboxContent {...checkboxProps} />; } } return result; }, // sort change sortChange() { let sortResult = ""; const { sortColumns, groupColumnItem, sortOption } = this; const { sortAlways } = sortOption; const currentField = groupColumnItem.field; const sortBy = sortColumns[currentField]; if (sortAlways) { sortResult = sortBy === "asc" ? "desc" : "asc"; } else { sortResult = sortBy === "asc" ? "desc" : sortBy === "desc" ? "" : "asc"; } this.dispatch(COMPS_NAME.VE_TABLE_THADER, EMIT_EVENTS.SORT_CHANGE, { currentField, sortResult, }); }, // get sort content getSortContent() { let result = null; const { sortColumns, groupColumnItem } = this; const currentField = groupColumnItem.field; if (Object.keys(sortColumns).includes(currentField)) { const sortBy = sortColumns[currentField]; const props = { class: clsName("sort"), }; result = ( <span {...props}> <VeIcon class={[ clsName("sort-icon"), clsName("sort-icon-top"), sortBy === "asc" ? "active" : "", ]} name={ICON_NAMES.SORT_TOP_ARROW} /> <VeIcon class={[ clsName("sort-icon"), clsName("sort-icon-bottom"), sortBy === "desc" ? "active" : "", ]} name={ICON_NAMES.SORT_BOTTOM_ARROW} /> </span> ); } return result; }, // get filter content getFilterContent() { let result = null; const { groupColumnItem } = this; if (groupColumnItem.filter) { // filter content props const filterProps = { props: { column: this.groupColumnItem, }, }; result = <HeaderFilterContent {...filterProps} />; } return result; }, // get filter custom content getFilterCustomContent() { let result = null; const { groupColumnItem } = this; if (groupColumnItem.filterCustom) { // filter content props const filterProps = { props: { column: this.groupColumnItem, }, }; result = <HeaderFilterCustomContent {...filterProps} />; } return result; }, // cell click cellClick(e, fn) { fn && fn(e); const { groupColumnItem } = this; this.dispatch(COMPS_NAME.VE_TABLE, EMIT_EVENTS.HEADER_CELL_CLICK, { event: e, column: groupColumnItem, }); }, // dblclick cellDblclick(e, fn) { fn && fn(e); }, // contextmenu cellContextmenu(e, fn) { fn && fn(e); const { groupColumnItem } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.HEADER_CELL_CONTEXTMENU, { event: e, column: groupColumnItem, }, ); }, // mouseenter cellMouseenter(e, fn) { fn && fn(e); }, // mouseleave cellMouseleave(e, fn) { fn && fn(e); const { groupColumnItem } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.HEADER_CELL_MOUSELEAVE, { event: e, column: groupColumnItem, }, ); }, // mousemove cellMousemove(e, fn) { fn && fn(e); const { groupColumnItem } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.HEADER_CELL_MOUSEMOVE, { event: e, column: groupColumnItem, }, ); }, // mouseover cellMouseover(e, fn) { fn && fn(e); const { groupColumnItem } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.HEADER_CELL_MOUSEOVER, { event: e, column: groupColumnItem, }, ); }, // mousedown cellMousedown(e, fn) { fn && fn(e); const { groupColumnItem } = this; this.dispatch( COMPS_NAME.VE_TABLE, EMIT_EVENTS.HEADER_CELL_MOUSEDOWN, { event: e, column: groupColumnItem, }, ); }, // mouseup cellMouseup(e, fn) { fn && fn(e); }, }, render(h) { const { groupColumnItem, getTheadThClass, getTheadThStyle, rowIndex, eventCustomOption, } = this; let content; if (typeof groupColumnItem.renderHeaderCell === "function") { const { ...column } = groupColumnItem; const renderResult = groupColumnItem.renderHeaderCell( { column, }, h, ); content = renderResult; } else { content = groupColumnItem.title; } // custom on cell event let customEvents = {}; if (eventCustomOption) { const { headerCellEvents } = eventCustomOption; customEvents = headerCellEvents ? headerCellEvents({ column: groupColumnItem, rowIndex }) : {}; } const { click, dblclick, contextmenu, mouseenter, mouseleave, mousemove, mouseover, mousedown, mouseup, } = customEvents; const events = { click: (e) => { this.cellClick(e, click); if ( this.isSortableCloumn && e.target instanceof HTMLTableCellElement ) { this.sortChange(); } }, dblclick: (e) => { this.cellDblclick(e, dblclick); }, contextmenu: (e) => { this.cellContextmenu(e, contextmenu); }, mouseenter: (e) => { this.cellMouseenter(e, mouseenter); }, mouseleave: (e) => { this.cellMouseleave(e, mouseleave); }, mousemove: (e) => { this.cellMousemove(e, mousemove); }, mouseover: (e) => { this.cellMouseover(e, mouseover); }, mousedown: (e) => { this.cellMousedown(e, mousedown); }, mouseup: (e) => { this.cellMouseup(e, mouseup); }, }; const thProps = { style: getTheadThStyle(groupColumnItem, rowIndex), class: getTheadThClass(groupColumnItem), attrs: { rowspan: groupColumnItem._rowspan, colspan: groupColumnItem._colspan, }, on: events, }; return ( <th {...thProps}> {/* checkbox content */} {this.getCheckboxContent()} {content} {/* sort content */} {this.getSortContent()} {/* filter content */} {this.getFilterContent()} {/* filter custom content */} {this.getFilterCustomContent()} </th> ); }, };