Luckysheet 远程搜索下拉 控件开发 : 揭秘二开全流程

前言

远程搜索下拉控件是非常常见的控件,应用在表单填写场景下,也是非常合适的,本例将带领大家实现以下效果,并真实了解并熟悉 luckysheet 的二开流程。

拓展单元格属性

在官网上,有一个常见问题,既然已知批注是直接加到单元格属性上,那么,我们拓展属性,是不是可以参考批注的实现方案?

我们设定以下是远程搜索下拉的单元格拓展属性:

ts 复制代码
// 扩展后的单元格对象
const cell = {
    v: null, // 原始值
    m: null, // 显示值
    ct: { fa: "General", t: "s" },
    // ... other properties

    // 新增远程搜索下拉配置
    remoteSelect: {
        // 是否启用远程搜索,[必传]
        enable: boolean,

        // 用户输入时的回调函数,用于获取远程数据
        onInput(value): Promise<Array<string>> {
            // 这个函数需要返回一个Promise对象,resolve一个数组,数组的元素为下拉选项对象
        }

        // 用户选定某个选项后的回调函数
        onSelect(item): void {
            // item 为用户选定的选项对象,值是onInput函数返回的数组中的某个元素
        }

        // 是否需要设定当前输入单元格的值 [可选]
        setValue(item): string{
           // item 为用户选定的选项对象,需要返回一个字符串,用于设定单元格的值
        },

        // 自定义类名  [可选]
        popperClass: string,
    },
};

何时触发?

在这个场景中,我们需要在用户输入值时,进行远程数据获取,渲染列表,因此,需要在用户进行编辑时,进行处理:

  1. 一个方案,是在初始化 inputHTML 时,将相关事件处理:
js 复制代码
 $("body").append(inputHTML)
 // 进行相关事件绑定: [伪代码]
 $input.on('input',function(){
 	// 这里是未知具体单元格信息的,需要通过外部传递
 	const remoteSelectOptions = Store.flowdata[r][c]
 	// 执行后续操作
 })
  1. 另一个方案,是用户双击时,唤起输入框后,进行判断:
js 复制代码
// handler.js
$("#luckysheet-cell-main, #luckysheetTableContent").dblclick(function(){
	// 这个函数是内置的哈,因此,可以直接获取到 r c
	// 判断当前单元格是否需要初始化远程搜索控件
	RemoteSelect.checkCellNeedRemoteSelect(row_index, col_index)
})

两种方案我都试过了,实现略有不同,但都可以实现,还是借助原生的 dblclick 好处理些。

校验远程搜索下拉

既然每一个单元格双击,都会触发这个校验,那么何时才需要初始化这个下拉框呢?

js 复制代码
// 判断当前单元格是否需要显示下拉框
checkCellNeedRemoteSelect: function(r, c) {
    // 通过 r c 获取单元格信息
    let cell = Store.flowdata[r][c];

    // 如果 cell 没有配置 remoteSelect 或者 remoteSelect.enable 为 false 则返回
    if (!cell || !cell.remoteSelect || !cell.remoteSelect.enable) {
        return;
    }
}

检验完成后,如果需要初始化校验,别忘了, 我们底层还要监听输入框事件哈:

js 复制代码
// 不然,开始监听 input 输入事件
$("#luckysheet-input-box .luckysheet-cell-input").off("input").on("input", function() {
        let value = $(this).text().trim(); // 获取用户输入的值
      
        if (cell.remoteSelect && cell.remoteSelect.onInput && typeof cell.remoteSelect.onInput == "function") {
            // 调用外部接口
            cell.remoteSelect
                .onInput(value)
                .then(function(dataList) {
                    $this.loading = false;
                    $this.showRemoteSelect(dataList);
                })
                .catch((error) => {
                    $this.loading = false;
                    $this.hideRemoteSelect();
                    console.log("请求接口错误", error);
                    tooltip.info('<i class="fa fa-exclamation-triangle"></i>', "接口请求失败");
                });
        }
    });

初始化下拉框

远程搜索的核心,就是下拉选项,当远程接口初始化完成后,执行如下:

js 复制代码
dataList.forEach((item) => {
	const $item = $(`<div class="${this.selectItemClass}">`)
		.text(item)
		.click(() => {
			// 触发选择回调
			if (cell.remoteSelect && cell.remoteSelect.onSelect && typeof cell.remoteSelect.onSelect === "function") {
    		cell.remoteSelect.onSelect(item);
			}
		})

这里就一个难点要处理,如何将下拉框定位到输入框的位置:

js 复制代码
// 这里采用巧方案,直接取输入框的位置
const $input = $("#luckysheet-input-box");
const left = parseInt($input.css("left")) || 0;
const top = parseInt($input.css("top")) || 0;

// 获取当前单元格的高度 行高
const [_row_pre, rowHeight] = rowLocation(this.r);

// 设置下拉框位置和宽度
$selectBox.css({
    top: `${top + rowHeight + 4}px`, // 在单元格下方显示
    left: `${left}px`,
});

总结

虽然代码看起来不复杂,但是了解luckysheet 的源码、实现思路,以及单元格拓展实现方案是非常重要的。

通过本次实现,我们初步了解了luckysheet的二次开发流程,在不破坏原有功能的基础上添加新特性。远程搜索下拉控件的实现展示了如何在现有表格组件基础上,通过合理的架构设计和代码组织,添加复杂交互功能。

相关推荐
MediaTea3 小时前
Python:模块 __dict__ 详解
开发语言·前端·数据库·python
字节跳动开源3 小时前
Midscene v1.0 发布 - 视觉驱动,UI 自动化体验跃迁
前端·人工智能·客户端
光影少年3 小时前
三维前端需要会哪些东西
前端·webgl
王林不想说话4 小时前
React自定义Hooks
前端·react.js·typescript
heyCHEEMS4 小时前
Uni-app 性能天坑:为什么 v-if 删不掉 DOM 节点
前端
马致良4 小时前
三年前写的一个代码工具,至今已被 AI Coding 完全取代。
前端·ai编程
橙某人4 小时前
LogicFlow 交互新体验:让锚点"活"起来,鼠标跟随动效实战!🧲
前端·javascript·vue.js
借个火er4 小时前
依赖注入系统
前端
借个火er4 小时前
项目介绍与环境搭建
前端