@blueking/vxe-table
Version:
一个基于 vue 的 PC 端表格组件,支持增删改查、虚拟树、列拖拽,懒加载、快捷菜单、数据校验、树形结构、打印、导入导出、自定义模板、渲染器、JSON 配置式...
1,207 lines (1,206 loc) • 40.2 kB
JavaScript
"use strict";
var _vue = require("vue");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _ui = require("../../../ui");
var _utils = require("../../../ui/src/utils");
var _util = require("../../src/util");
var _dom = require("../../../ui/src/dom");
var _log = require("../../../ui/src/log");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
getConfig,
renderer,
hooks,
getI18n
} = _ui.VxeUI;
const tableEditMethodKeys = ['insert', 'insertAt', 'insertNextAt', 'insertChild', 'insertChildAt', 'insertChildNextAt', 'remove', 'removeCheckboxRow', 'removeRadioRow', 'removeCurrentRow', 'getRecordset', 'getInsertRecords', 'getRemoveRecords', 'getUpdateRecords', 'getEditRecord', 'getActiveRecord', 'getSelectedCell', 'clearEdit', 'clearActived', 'clearSelected', 'isEditByRow', 'isActiveByRow', 'setEditRow', 'setActiveRow', 'setEditCell', 'setActiveCell', 'setSelectCell'];
hooks.add('tableEditModule', {
setupTable($xeTable) {
const {
props,
reactData,
internalData
} = $xeTable;
const {
refElem
} = $xeTable.getRefMaps();
const {
computeMouseOpts,
computeEditOpts,
computeCheckboxOpts,
computeTreeOpts,
computeValidOpts
} = $xeTable.getComputeMaps();
let editMethods = {};
let editPrivateMethods = {};
const getEditColumnModel = (row, column) => {
const {
model,
editRender
} = column;
if (editRender) {
model.value = (0, _util.getCellValue)(row, column);
model.update = false;
}
};
const setEditColumnModel = (row, column) => {
const {
model,
editRender
} = column;
if (editRender && model.update) {
(0, _util.setCellValue)(row, column, model.value);
model.update = false;
model.value = null;
}
};
const removeCellSelectedClass = () => {
const el = refElem.value;
if (el) {
const cell = el.querySelector('.col--selected');
if (cell) {
(0, _dom.removeClass)(cell, 'col--selected');
}
}
};
function syncActivedCell() {
const {
editStore,
tableColumn
} = reactData;
const editOpts = computeEditOpts.value;
const {
actived
} = editStore;
const {
row,
column
} = actived;
if (row || column) {
if (editOpts.mode === 'row') {
tableColumn.forEach(column => setEditColumnModel(row, column));
} else {
setEditColumnModel(row, column);
}
}
}
function insertTreeRow(newRecords, isAppend) {
const {
tableFullTreeData,
afterFullData,
fullDataRowIdData,
fullAllDataRowIdData
} = internalData;
const treeOpts = computeTreeOpts.value;
const {
rowField,
parentField,
mapChildrenField
} = treeOpts;
const childrenField = treeOpts.children || treeOpts.childrenField;
const funcName = isAppend ? 'push' : 'unshift';
newRecords.forEach(item => {
const parentRowId = item[parentField];
const rowid = (0, _util.getRowid)($xeTable, item);
const matchObj = parentRowId ? _xeUtils.default.findTree(tableFullTreeData, item => parentRowId === item[rowField], {
children: mapChildrenField
}) : null;
if (matchObj) {
const {
item: parentRow
} = matchObj;
const parentRest = fullAllDataRowIdData[(0, _util.getRowid)($xeTable, parentRow)];
const parentLevel = parentRest ? parentRest.level : 0;
let parentChilds = parentRow[childrenField];
let mapChilds = parentRow[mapChildrenField];
if (!_xeUtils.default.isArray(parentChilds)) {
parentChilds = parentRow[childrenField] = [];
}
if (!_xeUtils.default.isArray(mapChilds)) {
mapChilds = parentRow[childrenField] = [];
}
parentChilds[funcName](item);
mapChilds[funcName](item);
const rest = {
row: item,
rowid,
seq: -1,
index: -1,
_index: -1,
$index: -1,
items: parentChilds,
parent: parentRow,
level: parentLevel + 1,
height: 0,
oTop: 0
};
fullDataRowIdData[rowid] = rest;
fullAllDataRowIdData[rowid] = rest;
} else {
if (process.env.NODE_ENV === 'development') {
if (parentRowId) {
(0, _log.warnLog)('vxe.error.unableInsert');
}
}
afterFullData[funcName](item);
tableFullTreeData[funcName](item);
const rest = {
row: item,
rowid,
seq: -1,
index: -1,
_index: -1,
$index: -1,
items: tableFullTreeData,
parent: null,
level: 0,
height: 0,
oTop: 0
};
fullDataRowIdData[rowid] = rest;
fullAllDataRowIdData[rowid] = rest;
}
});
}
const handleInsertRowAt = (records, targetRow, isInsertNextRow) => {
const {
treeConfig
} = props;
const {
mergeList,
editStore
} = reactData;
const {
tableFullTreeData,
afterFullData,
tableFullData,
fullDataRowIdData,
fullAllDataRowIdData
} = internalData;
const treeOpts = computeTreeOpts.value;
const {
transform,
rowField,
mapChildrenField
} = treeOpts;
const childrenField = treeOpts.children || treeOpts.childrenField;
if (!_xeUtils.default.isArray(records)) {
records = [records];
}
const newRecords = (0, _vue.reactive)($xeTable.defineField(records.map(record => Object.assign(treeConfig && transform ? {
[mapChildrenField]: [],
[childrenField]: []
} : {}, record))));
if (_xeUtils.default.eqNull(targetRow)) {
// 如果为虚拟树
if (treeConfig && transform) {
insertTreeRow(newRecords, false);
} else {
newRecords.forEach(item => {
const rowid = (0, _util.getRowid)($xeTable, item);
const rest = {
row: item,
rowid,
seq: -1,
index: -1,
_index: -1,
$index: -1,
items: afterFullData,
parent: null,
level: 0,
height: 0,
oTop: 0
};
fullDataRowIdData[rowid] = rest;
fullAllDataRowIdData[rowid] = rest;
afterFullData.unshift(item);
tableFullData.unshift(item);
});
// 刷新单元格合并
mergeList.forEach(mergeItem => {
const {
row: mergeRowIndex
} = mergeItem;
if (mergeRowIndex > 0) {
mergeItem.row = mergeRowIndex + newRecords.length;
}
});
}
} else {
if (targetRow === -1) {
// 如果为虚拟树
if (treeConfig && transform) {
insertTreeRow(newRecords, true);
} else {
newRecords.forEach(item => {
const rowid = (0, _util.getRowid)($xeTable, item);
const rest = {
row: item,
rowid,
seq: -1,
index: -1,
_index: -1,
$index: -1,
items: afterFullData,
parent: null,
level: 0,
height: 0,
oTop: 0
};
fullDataRowIdData[rowid] = rest;
fullAllDataRowIdData[rowid] = rest;
afterFullData.push(item);
tableFullData.push(item);
});
// 刷新单元格合并
mergeList.forEach(mergeItem => {
const {
row: mergeRowIndex,
rowspan: mergeRowspan
} = mergeItem;
if (mergeRowIndex + mergeRowspan > afterFullData.length) {
mergeItem.rowspan = mergeRowspan + newRecords.length;
}
});
}
} else {
// 如果为虚拟树
if (treeConfig && transform) {
const matchMapObj = _xeUtils.default.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], {
children: mapChildrenField
});
if (matchMapObj) {
const {
parent: parentRow
} = matchMapObj;
const parentMapChilds = parentRow ? parentRow[mapChildrenField] : tableFullTreeData;
const parentRest = fullAllDataRowIdData[(0, _util.getRowid)($xeTable, parentRow)];
const parentLevel = parentRest ? parentRest.level : 0;
newRecords.forEach((item, i) => {
const rowid = (0, _util.getRowid)($xeTable, item);
if (process.env.NODE_ENV === 'development') {
if (item[treeOpts.parentField]) {
if (parentRow && item[treeOpts.parentField] !== parentRow[rowField]) {
(0, _log.errLog)('vxe.error.errProp', [`${treeOpts.parentField}=${item[treeOpts.parentField]}`, `${treeOpts.parentField}=${parentRow[rowField]}`]);
}
}
}
if (parentRow) {
item[treeOpts.parentField] = parentRow[rowField];
}
let targetIndex = matchMapObj.index + i;
if (isInsertNextRow) {
targetIndex = targetIndex + 1;
}
parentMapChilds.splice(targetIndex, 0, item);
const rest = {
row: item,
rowid,
seq: -1,
index: -1,
_index: -1,
$index: -1,
items: parentMapChilds,
parent: parentRow,
level: parentLevel + 1,
height: 0,
oTop: 0
};
fullDataRowIdData[rowid] = rest;
fullAllDataRowIdData[rowid] = rest;
});
// 源
if (parentRow) {
const matchObj = _xeUtils.default.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], {
children: childrenField
});
if (matchObj) {
const parentChilds = matchObj.items;
let targetIndex = matchObj.index;
if (isInsertNextRow) {
targetIndex = targetIndex + 1;
}
parentChilds.splice(targetIndex, 0, ...newRecords);
}
}
} else {
if (process.env.NODE_ENV === 'development') {
(0, _log.warnLog)('vxe.error.unableInsert');
}
insertTreeRow(newRecords, true);
}
} else {
if (treeConfig) {
throw new Error(getI18n('vxe.error.noTree', ['insert']));
}
let afIndex = -1;
// 如果是可视索引
if (_xeUtils.default.isNumber(targetRow)) {
if (targetRow < afterFullData.length) {
afIndex = targetRow;
}
} else {
afIndex = $xeTable.findRowIndexOf(afterFullData, targetRow);
}
// 如果是插入指定行的下一行
if (isInsertNextRow) {
afIndex = Math.min(afterFullData.length, afIndex + 1);
}
if (afIndex === -1) {
throw new Error(getI18n('vxe.error.unableInsert'));
}
afterFullData.splice(afIndex, 0, ...newRecords);
const tfIndex = $xeTable.findRowIndexOf(tableFullData, targetRow);
if (tfIndex > -1) {
tableFullData.splice(tfIndex + (isInsertNextRow ? 1 : 0), 0, ...newRecords);
} else {
tableFullData.push(...newRecords);
}
// 刷新单元格合并
mergeList.forEach(mergeItem => {
const {
row: mergeRowIndex,
rowspan: mergeRowspan
} = mergeItem;
if (mergeRowIndex > afIndex) {
mergeItem.row = mergeRowIndex + newRecords.length;
} else if (mergeRowIndex + mergeRowspan > afIndex) {
mergeItem.rowspan = mergeRowspan + newRecords.length;
}
});
}
}
}
const {
insertMaps
} = editStore;
newRecords.forEach(newRow => {
const rowid = (0, _util.getRowid)($xeTable, newRow);
insertMaps[rowid] = newRow;
});
$xeTable.cacheRowMap();
$xeTable.updateScrollYStatus();
$xeTable.handleTableData(treeConfig && transform);
if (!(treeConfig && transform)) {
$xeTable.updateAfterDataIndex();
}
$xeTable.updateFooter();
$xeTable.checkSelectionStatus();
if (reactData.scrollYLoad) {
$xeTable.updateScrollYSpace();
}
return (0, _vue.nextTick)().then(() => {
$xeTable.updateCellAreas();
return $xeTable.recalculate();
}).then(() => {
return {
row: newRecords.length ? newRecords[newRecords.length - 1] : null,
rows: newRecords
};
});
};
const handleInsertChildRowAt = (records, parentRow, targetRow, isInsertNextRow) => {
const {
treeConfig
} = props;
const treeOpts = computeTreeOpts.value;
const {
transform,
rowField,
parentField
} = treeOpts;
if (treeConfig && transform) {
if (!_xeUtils.default.isArray(records)) {
records = [records];
}
return handleInsertRowAt(records.map(item => Object.assign({}, item, {
[parentField]: parentRow[rowField]
})), targetRow, isInsertNextRow);
} else {
(0, _log.errLog)('vxe.error.errProp', ['tree-config.treeConfig=false', 'tree-config.treeConfig=true']);
}
return Promise.resolve({
row: null,
rows: []
});
};
const handleClearEdit = (evnt, targetRow) => {
const {
mouseConfig
} = props;
const {
editStore
} = reactData;
const {
actived,
focused
} = editStore;
const {
row,
column
} = actived;
const validOpts = computeValidOpts.value;
const mouseOpts = computeMouseOpts.value;
if (row || column) {
if (targetRow && (0, _util.getRowid)($xeTable, targetRow) !== (0, _util.getRowid)($xeTable, row)) {
return (0, _vue.nextTick)();
}
syncActivedCell();
actived.args = null;
actived.row = null;
actived.column = null;
$xeTable.updateFooter();
$xeTable.dispatchEvent('edit-closed', {
row,
rowIndex: $xeTable.getRowIndex(row),
$rowIndex: $xeTable.getVMRowIndex(row),
column,
columnIndex: $xeTable.getColumnIndex(column),
$columnIndex: $xeTable.getVMColumnIndex(column)
}, evnt || null);
}
(0, _vue.nextTick)(() => {
if (mouseConfig && mouseOpts.area && $xeTable.handleRecalculateCellAreas) {
return $xeTable.handleRecalculateCellAreas();
}
});
if (validOpts.autoClear) {
if (validOpts.msgMode !== 'full' || getConfig().cellVaildMode === 'obsolete') {
if ($xeTable.clearValidate) {
return $xeTable.clearValidate();
}
}
}
focused.row = null;
focused.column = null;
return (0, _vue.nextTick)();
};
editMethods = {
/**
* 往表格中插入临时数据
*
* @param {*} records
*/
insert(records) {
return handleInsertRowAt(records, null);
},
/**
* 往表格指定行中插入临时数据
* 如果 row 为空则从插入到顶部,如果为树结构,则插入到目标节点顶部
* 如果 row 为 -1 则从插入到底部,如果为树结构,则插入到目标节点底部
* 如果 row 为有效行则插入到该行的位置,如果为树结构,则有插入到效的目标节点该行的位置
* @param {Object/Array} records 新的数据
* @param {Row} targetRow 指定行
*/
insertAt(records, targetRow) {
return handleInsertRowAt(records, targetRow);
},
insertNextAt(records, targetRow) {
return handleInsertRowAt(records, targetRow, true);
},
insertChild(records, parentRow) {
return handleInsertChildRowAt(records, parentRow, null);
},
insertChildAt(records, parentRow, targetRow) {
return handleInsertChildRowAt(records, parentRow, targetRow);
},
insertChildNextAt(records, parentRow, targetRow) {
return handleInsertChildRowAt(records, parentRow, targetRow, true);
},
/**
* 删除指定行数据
* 如果传 row 则删除一行
* 如果传 rows 则删除多行
* 如果为空则删除所有
*/
remove(rows) {
const {
treeConfig
} = props;
const {
mergeList,
editStore,
selectCheckboxMaps
} = reactData;
const {
tableFullTreeData,
afterFullData,
tableFullData
} = internalData;
const checkboxOpts = computeCheckboxOpts.value;
const treeOpts = computeTreeOpts.value;
const {
transform,
mapChildrenField
} = treeOpts;
const childrenField = treeOpts.children || treeOpts.childrenField;
const {
actived,
removeMaps
} = editStore;
const insertDataRowMaps = Object.assign({}, editStore.insertMaps);
const pendingDataRowMaps = Object.assign({}, reactData.pendingRowMaps);
const {
checkField
} = checkboxOpts;
let delList = [];
if (!rows) {
rows = tableFullData;
} else if (!_xeUtils.default.isArray(rows)) {
rows = [rows];
}
// 如果是新增,则保存记录
rows.forEach(row => {
if (!$xeTable.isInsertByRow(row)) {
const rowid = (0, _util.getRowid)($xeTable, row);
removeMaps[rowid] = row;
}
});
// 如果绑定了多选属性,则更新状态
if (!checkField) {
const selectRowMaps = Object.assign({}, selectCheckboxMaps);
rows.forEach(row => {
const rowid = (0, _util.getRowid)($xeTable, row);
if (selectRowMaps[rowid]) {
delete selectRowMaps[rowid];
}
});
reactData.selectCheckboxMaps = selectRowMaps;
}
// 从数据源中移除
if (tableFullData === rows) {
rows = delList = tableFullData.slice(0);
internalData.tableFullData = [];
internalData.afterFullData = [];
$xeTable.clearMergeCells();
} else {
// 如果为虚拟树
if (treeConfig && transform) {
rows.forEach(row => {
const rowid = (0, _util.getRowid)($xeTable, row);
const matchMapObj = _xeUtils.default.findTree(tableFullTreeData, item => rowid === (0, _util.getRowid)($xeTable, item), {
children: mapChildrenField
});
if (matchMapObj) {
const rItems = matchMapObj.items.splice(matchMapObj.index, 1);
delList.push(rItems[0]);
}
const matchObj = _xeUtils.default.findTree(tableFullTreeData, item => rowid === (0, _util.getRowid)($xeTable, item), {
children: childrenField
});
if (matchObj) {
matchObj.items.splice(matchObj.index, 1);
}
const afIndex = $xeTable.findRowIndexOf(afterFullData, row);
if (afIndex > -1) {
afterFullData.splice(afIndex, 1);
}
});
} else {
rows.forEach(row => {
const tfIndex = $xeTable.findRowIndexOf(tableFullData, row);
if (tfIndex > -1) {
const rItems = tableFullData.splice(tfIndex, 1);
delList.push(rItems[0]);
}
const afIndex = $xeTable.findRowIndexOf(afterFullData, row);
if (afIndex > -1) {
// 刷新单元格合并
mergeList.forEach(mergeItem => {
const {
row: mergeRowIndex,
rowspan: mergeRowspan
} = mergeItem;
if (mergeRowIndex > afIndex) {
mergeItem.row = mergeRowIndex - 1;
} else if (mergeRowIndex + mergeRowspan > afIndex) {
mergeItem.rowspan = mergeRowspan - 1;
}
});
afterFullData.splice(afIndex, 1);
}
});
}
}
// 如果当前行被激活编辑,则清除激活状态
if (actived.row && $xeTable.findRowIndexOf(rows, actived.row) > -1) {
editMethods.clearEdit();
}
// 从新增中移除已删除的数据
rows.forEach(row => {
const rowid = (0, _util.getRowid)($xeTable, row);
if (insertDataRowMaps[rowid]) {
delete insertDataRowMaps[rowid];
}
if (pendingDataRowMaps[rowid]) {
delete pendingDataRowMaps[rowid];
}
});
editStore.insertMaps = insertDataRowMaps;
reactData.pendingRowMaps = pendingDataRowMaps;
$xeTable.updateFooter();
$xeTable.cacheRowMap();
$xeTable.handleTableData(treeConfig && transform);
if (!(treeConfig && transform)) {
$xeTable.updateAfterDataIndex();
}
$xeTable.checkSelectionStatus();
if (reactData.scrollYLoad) {
$xeTable.updateScrollYSpace();
}
return (0, _vue.nextTick)().then(() => {
$xeTable.updateCellAreas();
return $xeTable.recalculate();
}).then(() => {
return {
row: delList.length ? delList[delList.length - 1] : null,
rows: delList
};
});
},
/**
* 删除复选框选中的数据
*/
removeCheckboxRow() {
return editMethods.remove($xeTable.getCheckboxRecords()).then(params => {
$xeTable.clearCheckboxRow();
return params;
});
},
/**
* 删除单选框选中的数据
*/
removeRadioRow() {
const radioRecord = $xeTable.getRadioRecord();
return editMethods.remove(radioRecord || []).then(params => {
$xeTable.clearRadioRow();
return params;
});
},
/**
* 删除当前行选中的数据
*/
removeCurrentRow() {
const currentRecord = $xeTable.getCurrentRecord();
return editMethods.remove(currentRecord || []).then(params => {
$xeTable.clearCurrentRow();
return params;
});
},
/**
* 获取表格数据集,包含新增、删除、修改、标记
*/
getRecordset() {
const removeRecords = editMethods.getRemoveRecords();
const pendingRecords = $xeTable.getPendingRecords();
const delRecords = removeRecords.concat(pendingRecords);
// 如果已经被删除,则无需放到更新数组
const updateRecords = editMethods.getUpdateRecords().filter(row => {
return !delRecords.some(item => $xeTable.eqRow(item, row));
});
return {
insertRecords: editMethods.getInsertRecords(),
removeRecords,
updateRecords,
pendingRecords
};
},
/**
* 获取新增的临时数据
*/
getInsertRecords() {
const {
editStore
} = reactData;
const {
fullAllDataRowIdData
} = internalData;
const {
insertMaps
} = editStore;
const insertRecords = [];
_xeUtils.default.each(insertMaps, (row, rowid) => {
if (fullAllDataRowIdData[rowid]) {
insertRecords.push(row);
}
});
return insertRecords;
},
/**
* 获取已删除的数据
*/
getRemoveRecords() {
const {
editStore
} = reactData;
const {
removeMaps
} = editStore;
const removeRecords = [];
_xeUtils.default.each(removeMaps, row => {
removeRecords.push(row);
});
return removeRecords;
},
/**
* 获取更新数据
* 只精准匹配 row 的更改
* 如果是树表格,子节点更改状态不会影响父节点的更新状态
*/
getUpdateRecords() {
const {
keepSource,
treeConfig
} = props;
const {
tableFullData
} = internalData;
const treeOpts = computeTreeOpts.value;
if (keepSource) {
syncActivedCell();
if (treeConfig) {
return _xeUtils.default.filterTree(tableFullData, row => $xeTable.isUpdateByRow(row), treeOpts);
}
return tableFullData.filter(row => $xeTable.isUpdateByRow(row));
}
return [];
},
getActiveRecord() {
if (process.env.NODE_ENV === 'development') {
(0, _log.warnLog)('vxe.error.delFunc', ['getActiveRecord', 'getEditRecord']);
}
return this.getEditRecord();
},
getEditRecord() {
const {
editStore
} = reactData;
const {
afterFullData
} = internalData;
const el = refElem.value;
const {
args,
row
} = editStore.actived;
if (args && $xeTable.findRowIndexOf(afterFullData, row) > -1 && el.querySelectorAll('.vxe-body--column.col--active').length) {
return Object.assign({}, args);
}
return null;
},
/**
* 获取选中的单元格
*/
getSelectedCell() {
const {
editStore
} = reactData;
const {
args,
column
} = editStore.selected;
if (args && column) {
return Object.assign({}, args);
}
return null;
},
clearActived(row) {
// 即将废弃
if (process.env.NODE_ENV === 'development') {
(0, _log.warnLog)('vxe.error.delFunc', ['clearActived', 'clearEdit']);
}
return this.clearEdit(row);
},
/**
* 清除激活的编辑
*/
clearEdit(row) {
return handleClearEdit(null, row);
},
/**
* 清除所选中源状态
*/
clearSelected() {
const {
editStore
} = reactData;
const {
selected
} = editStore;
selected.row = null;
selected.column = null;
removeCellSelectedClass();
return (0, _vue.nextTick)();
},
isActiveByRow(row) {
if (process.env.NODE_ENV === 'development') {
(0, _log.warnLog)('vxe.error.delFunc', ['isActiveByRow', 'isEditByRow']);
}
// 即将废弃
return this.isEditByRow(row);
},
/**
* 判断行是否为激活编辑状态
* @param {Row} row 行对象
*/
isEditByRow(row) {
const {
editStore
} = reactData;
return editStore.actived.row === row;
},
setActiveRow(row) {
if (process.env.NODE_ENV === 'development') {
(0, _log.warnLog)('vxe.error.delFunc', ['setActiveRow', 'setEditRow']);
}
// 即将废弃
return editMethods.setEditRow(row);
},
/**
* 激活行编辑
*/
setEditRow(row, fieldOrColumn) {
const {
visibleColumn
} = internalData;
let column = _xeUtils.default.find(visibleColumn, column => (0, _utils.isEnableConf)(column.editRender));
if (fieldOrColumn) {
column = _xeUtils.default.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn;
}
return $xeTable.setEditCell(row, column);
},
setActiveCell(row, fieldOrColumn) {
if (process.env.NODE_ENV === 'development') {
(0, _log.warnLog)('vxe.error.delFunc', ['setActiveCell', 'setEditCell']);
}
// 即将废弃
return editMethods.setEditCell(row, fieldOrColumn);
},
/**
* 激活单元格编辑
*/
setEditCell(row, fieldOrColumn) {
const {
editConfig
} = props;
const column = _xeUtils.default.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn;
if (row && column && (0, _utils.isEnableConf)(editConfig) && (0, _utils.isEnableConf)(column.editRender)) {
return $xeTable.scrollToRow(row, column).then(() => {
const cell = $xeTable.getCellElement(row, column);
if (cell) {
editPrivateMethods.handleEdit({
row,
rowIndex: $xeTable.getRowIndex(row),
column,
columnIndex: $xeTable.getColumnIndex(column),
cell,
$table: $xeTable
});
internalData._lastCallTime = Date.now();
}
return (0, _vue.nextTick)();
});
}
return (0, _vue.nextTick)();
},
/**
* 只对 trigger=dblclick 有效,选中单元格
*/
setSelectCell(row, fieldOrColumn) {
const {
tableData
} = reactData;
const editOpts = computeEditOpts.value;
const column = _xeUtils.default.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn;
if (row && column && editOpts.trigger !== 'manual') {
const rowIndex = $xeTable.findRowIndexOf(tableData, row);
if (rowIndex > -1 && column) {
const cell = $xeTable.getCellElement(row, column);
const params = {
row,
rowIndex,
column,
columnIndex: $xeTable.getColumnIndex(column),
cell
};
$xeTable.handleSelected(params, {});
}
}
return (0, _vue.nextTick)();
}
};
editPrivateMethods = {
/**
* 处理激活编辑
*/
handleEdit(params, evnt) {
const {
editConfig,
mouseConfig
} = props;
const {
editStore,
tableColumn
} = reactData;
const editOpts = computeEditOpts.value;
const {
mode
} = editOpts;
const {
actived,
focused
} = editStore;
const {
row,
column
} = params;
const {
editRender
} = column;
const cell = params.cell || $xeTable.getCellElement(row, column);
const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod;
params.cell = cell;
if (cell && (0, _utils.isEnableConf)(editConfig) && (0, _utils.isEnableConf)(editRender)) {
// 激活编辑
if (!$xeTable.isPendingByRow(row)) {
if (actived.row !== row || (mode === 'cell' ? actived.column !== column : false)) {
// 判断是否禁用编辑
let type = 'edit-disabled';
if (!beforeEditMethod || beforeEditMethod(Object.assign(Object.assign({}, params), {
$table: $xeTable,
$grid: $xeTable.xegrid
}))) {
if (mouseConfig) {
editMethods.clearSelected();
if ($xeTable.clearCellAreas) {
$xeTable.clearCellAreas();
$xeTable.clearCopyCellArea();
}
}
$xeTable.closeTooltip();
if (actived.column) {
handleClearEdit(evnt);
}
type = 'edit-activated';
column.renderHeight = cell.offsetHeight;
actived.args = params;
actived.row = row;
actived.column = column;
if (mode === 'row') {
tableColumn.forEach(column => getEditColumnModel(row, column));
} else {
getEditColumnModel(row, column);
}
const afterEditMethod = editOpts.afterEditMethod;
(0, _vue.nextTick)(() => {
editPrivateMethods.handleFocus(params, evnt);
if (afterEditMethod) {
afterEditMethod(Object.assign(Object.assign({}, params), {
$table: $xeTable,
$grid: $xeTable.xegrid
}));
}
});
}
$xeTable.dispatchEvent(type, {
row,
rowIndex: $xeTable.getRowIndex(row),
$rowIndex: $xeTable.getVMRowIndex(row),
column,
columnIndex: $xeTable.getColumnIndex(column),
$columnIndex: $xeTable.getVMColumnIndex(column)
}, evnt);
// v4已废弃
if (type === 'edit-activated') {
$xeTable.dispatchEvent('edit-actived', {
row,
rowIndex: $xeTable.getRowIndex(row),
$rowIndex: $xeTable.getVMRowIndex(row),
column,
columnIndex: $xeTable.getColumnIndex(column),
$columnIndex: $xeTable.getVMColumnIndex(column)
}, evnt);
}
} else {
const {
column: oldColumn
} = actived;
if (mouseConfig) {
editMethods.clearSelected();
if ($xeTable.clearCellAreas) {
$xeTable.clearCellAreas();
$xeTable.clearCopyCellArea();
}
}
if (oldColumn !== column) {
const {
model: oldModel
} = oldColumn;
if (oldModel.update) {
(0, _util.setCellValue)(row, oldColumn, oldModel.value);
}
if ($xeTable.clearValidate) {
$xeTable.clearValidate(row, column);
}
}
column.renderHeight = cell.offsetHeight;
actived.args = params;
actived.column = column;
setTimeout(() => {
editPrivateMethods.handleFocus(params, evnt);
});
}
focused.column = null;
focused.row = null;
$xeTable.focus();
}
}
return (0, _vue.nextTick)();
},
/**
* @deprecated
*/
handleActived(params, evnt) {
return editPrivateMethods.handleEdit(params, evnt);
},
/**
* 处理取消编辑
* @param evnt
* @returns
*/
handleClearEdit,
/**
* 处理聚焦
*/
handleFocus(params) {
const {
row,
column,
cell
} = params;
const {
editRender
} = column;
const editOpts = computeEditOpts.value;
if ((0, _utils.isEnableConf)(editRender)) {
const compRender = renderer.get(editRender.name);
let autoFocus = editRender.autofocus || editRender.autoFocus;
let autoSelect = editRender.autoSelect || editRender.autoselect;
let inputElem;
// 是否启用聚焦
if (editOpts.autoFocus) {
if (!autoFocus && compRender) {
autoFocus = compRender.tableAutoFocus || compRender.tableAutofocus || compRender.autofocus;
}
if (!autoSelect && compRender) {
autoSelect = compRender.tableAutoSelect || compRender.autoselect;
}
// 如果指定了聚焦 class
if (_xeUtils.default.isFunction(autoFocus)) {
inputElem = autoFocus(params);
} else if (autoFocus) {
if (autoFocus === true) {
// 自动匹配模式,会自动匹配第一个可输入元素
inputElem = cell.querySelector('input,textarea');
} else {
inputElem = cell.querySelector(autoFocus);
}
if (inputElem) {
inputElem.focus();
}
}
}
if (inputElem) {
if (autoSelect) {
inputElem.select();
} else {
// 保持一致行为,光标移到末端
if (_dom.browse.msie) {
const textRange = inputElem.createTextRange();
textRange.collapse(false);
textRange.select();
}
}
} else {
// 是否自动定位
if (editOpts.autoPos) {
if (!column.fixed) {
// 显示到可视区中
$xeTable.scrollToRow(row, column);
}
}
}
}
},
/**
* 处理选中源
*/
handleSelected(params, evnt) {
const {
mouseConfig
} = props;
const {
editStore
} = reactData;
const mouseOpts = computeMouseOpts.value;
const editOpts = computeEditOpts.value;
const {
actived,
selected
} = editStore;
const {
row,
column
} = params;
const isMouseSelected = mouseConfig && mouseOpts.selected;
const selectMethod = () => {
if (isMouseSelected && (selected.row !== row || selected.column !== column)) {
if (actived.row !== row || (editOpts.mode === 'cell' ? actived.column !== column : false)) {
handleClearEdit(evnt);
editMethods.clearSelected();
if ($xeTable.clearCellAreas) {
$xeTable.clearCellAreas();
$xeTable.clearCopyCellArea();
}
selected.args = params;
selected.row = row;
selected.column = column;
if (isMouseSelected) {
editPrivateMethods.addCellSelectedClass();
}
$xeTable.focus();
if (evnt) {
$xeTable.dispatchEvent('cell-selected', params, evnt);
}
}
}
return (0, _vue.nextTick)();
};
return selectMethod();
},
addCellSelectedClass() {
const {
editStore
} = reactData;
const {
selected
} = editStore;
const {
row,
column
} = selected;
removeCellSelectedClass();
if (row && column) {
const cell = $xeTable.getCellElement(row, column);
if (cell) {
(0, _dom.addClass)(cell, 'col--selected');
}
}
}
};
return Object.assign(Object.assign({}, editMethods), editPrivateMethods);
},
setupGrid($xeGrid) {
return $xeGrid.extendTableMethods(tableEditMethodKeys);
}
});