easytable 回车跳转下一格单元格

Posted on 2023-07-06 16:40  ${妖气}  阅读(108)  评论(0编辑  收藏  举报

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提供的外部方法还是挺多的,很多看起来很复杂的需求都能实现,只是不太优雅 😐