格子表单GRID-FORM | 必填项检验 BUG 修复实录

格子表单/GRID-FORM已在Github 开源,如能帮到您麻烦给个星🤝

GRID-FORM 系列文章

#1 缘起

格子表单支持设置字段为必填项,组件会在数据提交前自检,发现有必填字段留空,则抛出异常。

增加子(嵌套)表单功能后,上述校验出现 BUG 🐛,感谢热心网友的 ISSUE 提醒

#1.1 原因分析

原校验流程:

  1. 表单初始化时,构建必填项集合 formRequired : Map<String, Object>(以字段编号作为 KEY,元素包括:label/字段中文,msg/提示信息,regex/正则表达式)
  2. 校验时,遍历 formRequired ,匹配格则
  3. 若有字段(1个或多个)检查未通过,抛出异常

代码如下:

const _checkRequire = formObj=>{
    let fails = []
    Object.keys(formRequired).forEach(key=>{
        let { regex, msg, label } = formRequired[key]
        if(!formObj[key])   fails.push(`${label}${key})未填写`)
        else{
            if(!!regex && !RegExp(regex).test(formObj[key])) {
                fails.push(msg||`${label}${key})校验未通过`)
            }
        }
    })

    if(fails.length){
        props.debug && track(`[表单检查]`, fails)
        return emits("failed", fails)
    }
}

子表单下,字段编号可能重复,嵌套对象下遍历时不能正常匹配。如上图表单的校验过程 :

// 构建的规则
const formRequired = {
	school: { label:"学校名称", regex: "", msg:"" }
}

// 用户填写表单
const formData = {
	name: "fdgs",
	origin: "21,
	age: 123,
	educates: [
		{ type:"小学", from:"2024-02-18", school:"e121321" }
	]
}

// 检验时,遍历 formRequired,提取出 school,发现在 formData 中没有 formData['school'],于是报错

#2 思路

首先想到的解决方案,就是支持嵌套对象的检查:递归对当前层级的数据对象进行检查,直至没有下层嵌套。

/**
 * 检测必填项
 * 子表单(非 SIMPLE)必填无法正常检测
 *      https://github.com/0604hx/grid-form/issues/3
 *
 * @param {Array<import('.').FormItem>} items - 表单定义项
 * @param {Object} bean - 与 items 对应的数据对象
 * @param {Array<String>} fails - 错误清单
 * @param {String} prefix - 前缀文本
 */
const _checkRequire = (items, bean, fails, prefix="")=>{
    for(const item of items){
        if(item._container === true){
            switch(item.category){
                case SINGLE:
                    _checkRequire(item.items, bean[item._uuid]||{}, fails)
                    break
                case MULTIPLE:
                    const rows = bean[item._uuid]
                    if(Array.isArray(rows)){
                        for (let i = 0; i < rows.length; i++) {
                            const row = rows[i]
                            _checkRequire(item.items, row, fails, `[${item._text||item.title}的第${i+1}条]`)
                        }
                    }
                    break
                default:
                    _checkRequire(item.items, bean, fails)
            }
        }
        else if(item._required == true){
            //检查必填表单项是否符合预期
            if(!bean[item._uuid])
                fails.push(`${prefix}${item._text}${item._uuid})未填写`)
            else{
                if(!!item._regex && !RegExp(item._regex).text(bean[item._uuid]))
                    fails.push(prefix+(item._message || `${item._text}${item._uuid})校验未通过:${item._regex}`))
            }
        }
    }
}

新思路删除了中间变量 formRequired,仅在提交前遍历全部表单项进行校验,能够精准到子表单的某一行,理论上支持无限嵌套😎。

#3 尾声

修复后,效果如下:

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-15 02:22:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-15 02:22:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-15 02:22:02       82 阅读
  4. Python语言-面向对象

    2024-03-15 02:22:02       91 阅读

热门阅读

  1. 突破编程_C++_设计模式(模板方法模式)

    2024-03-15 02:22:02       31 阅读
  2. 大脑和人工智能克服遗忘

    2024-03-15 02:22:02       35 阅读
  3. Flask学习(二):flask模板渲染

    2024-03-15 02:22:02       43 阅读
  4. docker部署keepalived(搭建keepalived)

    2024-03-15 02:22:02       33 阅读
  5. 日常开发有用到临时表吗?

    2024-03-15 02:22:02       41 阅读
  6. uView Calendar 日历

    2024-03-15 02:22:02       33 阅读
  7. react native使用TS实现路由

    2024-03-15 02:22:02       37 阅读
  8. 洛谷 B3625 迷宫寻路

    2024-03-15 02:22:02       39 阅读
  9. 修复Jenkins fossa扫描的时候报错的问题

    2024-03-15 02:22:02       44 阅读
  10. 24计算机考研调剂 | 浙江工商大学【官方】

    2024-03-15 02:22:02       44 阅读