easytable 回车跳转下一格单元格
就是不用tab切换单元格,就是要用Enter 😃
实现思路
EasyTable默认的Enter效果:跳转选择同一列中下一行的单元格。在单元格编辑模式下,默认事件是退出编辑,同时跳转单元格
因此,要区分出表格的“编辑模式”和”选中模式”:
- 在编辑模式下,跳转下一格可以编辑的单元格,并进入编辑状态;
- 在选中模式下,回车进入可编辑单元格,在不可编辑单元格则保持不动。
实现逻辑
首先需要获取到表格的两种状态,可以通过表格提供的事件自定义绑定上表格的click事件,获取当前表格的选中单元格,并将其存起来,然后在编辑模式的回调中使用。
以下是详细的方法
step1. 获取当前表格选中的单元格
通过绑定表格的自定义事件click,获取表格的实例对象中的 cellSelectionData: { currentCell }
<template>
...
<ve-table
ref="easyTable"
...
:event-custom-option="easyTableCustomerEventOption"
... />
</tempalte>
<script>
easyTableCustomerEventOption: {
bodyCellEvents: ({ row, column, rowIndex }) => {
return {
click: () => {
// 每次点击更新选择的cell信息
const { cellSelectionData: { currentCell } } = this.$refs['easyTable'];
// 将当前点击的单元格位置信息存到data中
this.easyTableCellSelectionData = Object.assign({}, currentCell); // 避免与表格实例绑定
},
... // 还可以绑定双击dbclick,获取进入编辑模式的回调
}
}
}
</script>
step2. 保存在表格进入编辑状态前的单元格信息
可以通过 editOption
来调用关于编辑状态的回调方法
<template>
...
<ve-table
ref="easyTable"
...
:editOption="easyTableEditorOptions"
...
/>
</tempalte>
<script>
easyTableEditorOptions: {
/**
* 单元格编辑前事件
* @param {Object} row 行数据
* @param {Object} column 列数据
*/
beforeStartCellEditing: ({ row, column }) => {
// 进入编辑模式,设置当前编辑的单元格信息
this.easyTableEditorRow = row; // 编辑单元格的行数据
this.easyTableEditorColumn = column; // 编辑单元格的列数据
this.isEasyTableEditorModel = true; // 单元格是否处于编辑状态
},
... // 还有编辑完成前、编辑后的回调
}
</script>
step3. 在初始化表格时,挂上全局键盘输入事件监听
可以单独声明一个方法,用于初始化表格,可以处理在表格里面插入空白行、加入筛选功能等。
setCellSelection
设置指定单元格选中
startEditingCell
设置指定单元格进入编辑状态
/**
* 初始化easyTable
*/
initEasyTable() {
// 绑定回车监听事件
window.addEventListener('keydown', this.listenKeydown);
},
/**
* 键盘输入事件监听方法
* @param {Object} event 按键事件
*/
listenKeydown(event) {
const { keyCode } = event;
let prevCellSelectionData; // 上一次选中的单元格数据
switch (keyCode) {
case 13: // Enter按键
// 表格编辑模式下,回车跳转到当前行下一格单元格,进入选择模式
if (this.isEasyTableEditorModel) {
// step1 获取单元格当前坐标
let { rowKey } = this.easyTableEditorRow, // 下一格/行 表格Y轴坐标
colKey = this.easyTableEditorColumn.field, // 下一格/行 表格X轴坐标,默认是当前列的field值,在没有下一格可编辑单元格时停留在当前单元格
// 当前格表格X轴坐标,即列配置项在列配置数据中的索引值
xCoord = this.easyTableColumns.findIndex(item => item.field === this.easyTableEditorColumn.field);
// step2 设置回车后"下一格/行"的坐标
// 当前单元格所在列是"数量"时,跳转到下一行中
if (this.easyTableEditorColumn.field === 'qty') { // 这里也可以换成需要判断跳转行的field值
colKey = 'itemLength'; // 跳转下一行时,单元格聚焦到"宽度"
rowKey++;
if (rowKey === this.tableData.length) { // 先判断下一行是否为最后一行
this.copyItem(Object.assign({}, this.easyTableEditorRow, {rowKey, itemLength: 0, itemWidth: 0, qty: 0}), rowKey);
} else { // 如果下一行是空行(产品编码itemNo和产品名称itemName均为空),复制当前行内容到下一行,同时重置宽高数量
const { itemNo, itemName } = this.tableData[rowKey];
if (itemNo === '' && itemName === '')
this.replaceOrderDetailsRowData(rowKey, this.easyTableEditorRow);
}
} else { // 普通单元格,则跳转到当前行的下一个可编辑单元格
for (let i = xCoord + 1; i < this.easyTableColumns.length; i++) {
const { edit, field } = this.easyTableColumns[i];
if (edit) {
colKey = field;
break;
}
}
}
// 执行跳转编辑
this.$nextTick(() => {
this.clearEasyTableModifyMode();
this.jumpToEasyTableEditor(rowKey, colKey);
});
} else { // 表格正常模式下,回车进入表格编辑模式
const { rowKey, colKey } = this.easyTableCellSelectionData,
{ edit } = this.easyTableColumns.find(item => item.field === colKey);
// 判断回车的单元格是否不可编辑
if (edit) {
this.jumpToEasyTableEditor(rowKey, colKey);
} else {
this.$refs.easyTable.setCellSelection({ rowKey, colKey });
}
}
break;
...
}
},
/**
* 跳转可编辑单元格方法
* @param {Number} rowKey 行索引
* @param {String} colKey 列索引
*/
jumpToEasyTableEditor(rowKey, colKey) {
const { isNumber } = this.easyTableColumns.find(item => item.field === colKey),
rowData = this.tableData[rowKey][colKey];
// 单元格格式为数值,同时值为0,跳转同时将输入框的内容设为空
this.$nextTick(() => {
this.$refs.easyTable.stopEditingCell();
if (isNumber && Number(rowData) === 0) {
this.$refs.easyTable.startEditingCell({ rowKey, colKey, defaultValue: '' });
} else { // 单元格没有格式,正常跳转
this.$refs.easyTable.startEditingCell({ rowKey, colKey });
}
});
// 将表格视图跟着一起跳转过去
this.$refs.easyTable.scrollToRowKey({ rowKey });
this.$refs.easyTable.scrollToColKey({ colKey });
}
以上就是使用回车跳转下一行的实现,总的来说就是EasyTable并不提供这类功能,它是基于Excel的功能来开发的一款插件
但EasyTable提供的外部方法还是挺多的,很多看起来很复杂的需求都能实现,只是不太优雅 😐