Ant Design 动态增减form表单,第二三项根据第一项选中内容动态展示内容

news2024/11/15 19:58:40

效果图:
在这里插入图片描述

选中第一项下拉框,第二第三项展示在这里插入图片描述
点击添加条件,第二条仍然只展示第一项select框
在这里插入图片描述

后端返回数据格式:

ruleList:[
	{name:'通话时长',key:'TALK_TIME',type:’INT‘,unitName:'秒',
		operaObj:[{name:'>=',value:'>='},{name:'<=',value:'<='}],
		restrValues:null
	},
	{name:'是否成功',key:'IS_SUCCESS',type:’BOOLEAN‘,unitName:'',
		operaObj:[{name:'=',value:'='}],
		restrValues:[{name:'是',value:true},{name:'否',value:false}]
	},
	{name:'通话状态',key:'CALL_STATUS',type:’MULTI_SELECT‘,unitName:'',
		operaObj:[{name:'=',value:'in'}],
		restrValues:[{name:'黑名单',value:’1‘},{name:'忙碌',value:’2‘}]
	}
]

根据选中的第一项,动态展示第二项第三项,以及第三项的类型是下拉框还是input,和单位unitName
代码:

import { ModalForm } from '@ant-design/pro-form';
import type { FormInstance } from 'antd';

const manageFormRef = useRef<FormInstance>();
const [formData, setFormDate] = useState({
	ruleConditionDTOList: [null]
});


<ModalForm
	title='添加'
	// 弹窗开关,跟目前主要所写逻辑无关,可以先不管,按照你自己的弹窗开关事件即可
    open={visible}
    width={650}
    formRef={manageFormRef}
    layout='vertical'
    autoComplete='off'
    labelCol={{ span: 12 }}
    onFieldsChange={() => setFormDate(manageFormRef.current?.getFieldValue())}
    // 默认初始化值
    initialValues={
    	{
        	isAddToBlacklist: false,
            ruleConditionDTOList: [{}]
         }
    }
    // 弹窗关闭
    onOpenChange={onClose}
    // 提交表单
    onFinish={handleOnFinish}
>
<Form.Item label='同时满足以下条件'>
	<Form.List name="ruleConditionDTOList">
    	{(fields, { add, remove }) => (
        	<>
            	{fields.map((field, index) => (
                	<Space key={field.key} style={{ display: 'flex', flexWrap: 'wrap', marginBottom: 8 }} align="baseline">
                    	<Form.Item
                        	name={[field.name, 'key']}
                            rules={[{ required: true, message: '请选择条件' }]}
                       	>
                        <Select
                        	placeholder="请选择条件"
                            style={{ width: 200 }}
                            onChange={(val) => handleChange(val, field, index)}
                        >
                        	{ruleList && ruleList.map((item: any) => (
                            	<Select.Option value={item.key} fieldNames={item}>{item.name}</Select.Option>
                             ))}
                         </Select>
                     </Form.Item>
					// 第一项有值,显示第二项
                    {formData?.ruleConditionDTOList[index]?.key && 			<Form.Item

                     	name={[field.name, 'operator']}
                        rules={[{ required: true, message: '请选择' }]}
                    >
                    	<Select style={{ width: 100 }} placeholder="请选择">
                        	{ruleList && ruleList.find(v => formData.ruleConditionDTOList[index].key == v.key)?.operaObj.map((item: any) => (
                             	<Select.Option value={item.value}>{item.name}</Select.Option>
                            ))}
                        </Select>
                    </Form.Item>
                	}
                	// 第一项有值,展示第三项,根据第一项的type,动态展示第三项是input或是select或是多选,我这里写了个函数
                	{formData?.ruleConditionDTOList[index]?.key && getModel(formData?.ruleConditionDTOList[index]?.key, field, index)}
                	// form表单组的长度大于1,显示删除按钮,否则隐藏
                	{fields.length > 1 &&
                		<DeleteOutlined
                    		style={{ color: 'rgb(43, 132, 255)' }}
                        	className="dynamic-delete-button"
                        	onClick={() => remove(field.name)}
                     	/>}
                	</Space>
                ))}
            	<Form.Item>
            		<Button style={{ width: '100px' }} type="primary" onClick={() => add()} block>添加条件</Button>
            	</Form.Item>
            </>
        )}
     </Form.List>
</Form.Item>
</ModalForm>

// 根据type类型动态展示第三项要展示的内容
const getModel = (key: any, field: any, index: Number) => {
        const item = ruleList.find((v: any) => v.key == key);
        const types = {
            INT: (field: any, item: any) => {
                return <Form.Item
                    name={[field.name, 'value']}
                    rules={[{ required: true, message: '请输入' }]}
                >
                    <Input placeholder="请输入" style={{ width: 100 }} suffix={item.unitName} />
                </Form.Item>
            },
            // 多选下拉
            MULTI_SELECT: (field: any, item: any) => {
                return <Form.Item
                    name={[field.name, 'value']}
                    rules={[{ required: true, message: '请选择' }]}
                >
                    <Select mode="multiple" style={{ width: 200 }}>
                        {item.restrValues.map((v: any) => (
                            <Select.Option value={v.value}>{v.name}</Select.Option>
                        ))}
                    </Select>
                </Form.Item>
            },
            BOOLEAN: (field: any, item: any) => {
                return <Form.Item
                    name={[field.name, 'value']}
                    rules={[{ required: true, message: '请选择' }]}
                >
                    <Select style={{ width: 100 }}>
                        {item.restrValues.map((v: any) => (
                            <Select.Option value={v.value}>{v.name}</Select.Option>
                        ))}
                    </Select>
                </Form.Item>
            }

        }
        return types[item.type](field, item, index) ?? null;
    },
    // 选中第一项第二三项清空
    const handleChange = (val: any, field: any, index: any) => {
        const { ruleConditionDTOList } = formData
        ruleConditionDTOList[index] = Object.assign(ruleConditionDTOList[index] ?? {}, {
            key: val,
            operator: null,
            value: undefined
        })
        manageFormRef.current?.setFieldValue('ruleConditionDTOList', ruleConditionDTOList);
        setFormDate(manageFormRef.current?.getFieldValue());
        console.log(manageFormRef.current?.getFieldValue(), '置空');
    }


// 编辑时数据回显,后端返回的数据

data:{
	ruleConditionDTOList:[
		{name:'通话状态',key:'CALL_STATUS',type:'MULTI_SELECT',operator:'in',unitName:'',value:'1,2'},
		{name:'通话时长',key:'TALK_TIME',type:'INT',operator:'>=',unitName:'秒'}
	]
}

回显

useEffect(()=>{
	// 点击编辑,传的tagData单行row
	if(tagData){
		// 由于我获取接口都是异步,赋值时需要setTimeout一下
		setTimeout(() => {
                const { ruleConditionDTOList: list } = tagData
                let arr:any = []
                list?.map((v:any) => {
                	// 写个辅助函数,根据不同type,对value进行不同的操作
                    const getValue = (type: any) => {
                        const types = {
                            INT: () => {
                                return v.value
                            },
                            BOOLEAN: () => {
                                return Boolean(v.value)
                            },
                            MULTI_SELECT: () => {
                                const value = v?.value.split(',')
                                return value
                            }
                        }
                        return types[type]() ?? ''
                    }
                    const object = {
                        name: v.name,
                        key: v.key,
                        operator: v.operator,
                        value: getValue(v.type),
                        type: v.type,
                        unitName: v.unitName
                    }
                    arr.push(object)
                })
                manageFormRef.current?.setFieldsValue({
                    ruleConditionDTOList: arr
                })
                setFormDate(manageFormRef.current?.getFieldsValue())
            }, 300);
	}
},[tagData])

提交数据部分就不写了,提交跟接口相对应的数据就行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1713065.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多输入多输出 | MATLAB实现BiTCN(双向时间卷积神经网络)多输入多输出预测

多输入多输出 | MATLAB实现BiTCN(双向时间卷积神经网络)多输入多输出预测 目录 多输入多输出 | MATLAB实现BiTCN(双向时间卷积神经网络)多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BiTCN双向时间卷积神经网络多输入多输出预测 1.data为数据…

HNU-计算机体系结构-实验1-RISC-V流水线

计算机体系结构 实验1 计科210X 甘晴void 202108010XXX 1 实验目的 参考提供为了更好的理解RISC-V&#xff0c;通过学习RV32I Core的设计图&#xff0c;理解每条指令的数据流和控制信号&#xff0c;为之后指令流水线及乱序发射实验打下基础。 参考资料&#xff1a; RISC-…

13种即插即用涨点模块分享!含注意力机制、卷积变体、Transformer变体

朋友们&#xff0c;你们想发paper的时候有没有被创新点、改模型、改代码折磨过&#xff1f;今天我想分享一个前期又快又省事的方法&#x1f606; 就是用即插即用的模块“缝合”&#xff0c;加入自己的想法快速搭积木炼丹。 这种方法可以简化模型设计&#xff0c;减少冗余工作…

MySQL 数据表的基本操作

文章目录 【 1. MySQL 创建数据表 】【 2. MySQL 查看表 】2.1 DESCRIBE/DESC 以表格的形式展示表2.2 SHOW CREATE TABLE 以SQL语句的形式展示表 【 3. 修改数据表 】3.1 修改表名3.2 修改表字符集3.3 添加字段在末尾添加字段在开头添加字段在中间添加字段 3.3 修改/删除字段修…

【java-数据结构19-队列的模拟实现】

上篇文章&#xff0c;小编已经带大家一起认识了队列&#xff0c;并且对队列的方法进行调用测试&#xff0c;下面我们将模拟实现一个队列&#xff0c;话不多说&#xff0c;上正文~ 1.队列的模拟实现 队列的实现方法和链表的实现方式一模一样&#xff0c;这里我们首选双链表&…

MT2075 礼物

思路&#xff1a; x,y为质数&#xff0c;若x2,y3&#xff0c;则xy的最小公倍数6既不能给A也不能给B。 所以假设共有V个数&#xff0c;在1-V中&#xff0c;可以选的个数为&#xff1a;V-⌊V/(x*y)⌋ 个。&#xff08;⌊V/(x*y)⌋为V个数中有多少个xy的公倍数&#xff09; 所以…

股票量化交易上手,一个特别简单却长期可用的交易策略,官方接口

股票实现程序化自动化交易的三个基础&#xff1a;获取数据、执行交易、查询账户。 以后说到策略示例的时候就不介绍接口的基础使用方法了&#xff0c;随便一个策略把过程写出来都会很啰嗦&#xff0c;尽量压缩内容吧&#xff0c;这些内容是面向新手的&#xff0c;大佬们忽略细节…

护眼落地台灯十大知名品牌哪款最好?十大经典落地灯品牌推荐

护眼落地灯十大知名品牌哪款最好&#xff1f;随着快经济时代的到来&#xff0c;人们在学业以及事业上的压力也日益增加&#xff0c;不少朋友反应在日常工作、学习是经常出现眼部疲劳的状况&#xff0c;甚至会时不时出现眼睛干涩、流泪&#xff0c;对学习、工作状态造成了极大的…

【全开源】知识付费问答社区(FastAdmin+ThinkPHP)

此系统是一款基于FastAdmin和ThinkPHP开发的知识付费问答社区系统&#xff0c;提供全部前后台无加密源代码&#xff0c;拥有强大的付费提问、付费阅读、付费查看、付费邀请、全文搜索等功能模块&#xff0c;其整合了强大的标签模块和专区模块&#xff0c;让问题和文章更好的归类…

删除的短信怎么恢复?专业与非专业方法的全面比较

在日常清理手机内存的过程中&#xff0c;我们可能会不小心删除短信。这些短信可能包含重要的数据和联系人信息。面对这种情况&#xff0c;许多人会感到困惑和无助。那么&#xff0c;删除的短信怎么恢复呢&#xff1f;本文将为您全面比较专业与非专业的方法&#xff0c;帮助您找…

【信息学奥赛】两个整型变量的值交换

【信息学奥赛】两个整型变量的值交换 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 编写如下一个函数&#xff0c;用于将两个整型变量的值交换 输入&#xff1a; 两个数 输出&#xff1a; 交换后的两个数 样例输入&#xff1a; 3 2样…

Redis学习篇3:缓存更新策略与数据更新、淘汰策略

一、缓存更新策略 二、主动更新 三、过期策略 3.1 如何知道过期&#xff1f; 3.2 删除策略 四、内存淘汰策略 数据淘汰策略-使用建议 一、缓存更新策略 Redis是基于内存的数据库&#xff0c;它的优点就是在对数据进行操作的时候快&#xff0c;并且通过…

【全开源】驾校管理系统源码(FastAdmin+ThinkPHP)

一款基于FastAdminThinkPHP开发的驾校管理系统&#xff0c;驾校管理系统(DSS)主要面向驾驶学校实现内部信息化管理&#xff0c;让驾校管理者和工作人员更高效、更快捷的完成枯燥无味的工作&#xff0c;让工作更有条理。改变驾校传统的手工或半手工Excel文档管理的工作方式。多驾…

深入探索C++继承机制:从概念到实践的全面指南

目录 继承的概念及定义 继承的概念 继承的定义 定义格式 继承方式和访问限定符 继承基类成员访问方式的变化 默认继承方式 基类和派生类对象赋值转换 继承中的作用域 派生类的默认成员函数 继承与友元 继承与静态成员 继承的方式 菱形虚拟继承 菱形虚拟继承原理 继承…

vue项目关于loading问题

前言 因全局加loading会出现全白屏的遮罩层&#xff0c;影响美观&#xff0c;所以一般考虑局部加loading&#xff0c;比如是表格&#xff0c;表单等就加上loading 解决办法 v-loading“loading” element-loading-background“rgba(255, 255, 255, 0.6)” const loading re…

精酿啤酒:品质与口感在消费者选择中的权重分析

在啤酒市场中&#xff0c;消费者选择的影响因素众多&#xff0c;其中品质与口感是两个核心要素。对于Fendi club啤酒而言&#xff0c;品质与口感的权重分析在消费者选择中显得尤为重要。 品质是消费者选择啤酒的首要因素。随着消费者对啤酒认知的提高&#xff0c;他们对品质的…

论文《Sensor and Sensor Fusion Technology in Autonomous Vehicles: A Review》详细解析

论文《Sensor and Sensor Fusion Technology in Autonomous Vehicles: A Review》详细解析 摘要 该论文对自动驾驶汽车中的传感器和传感器融合技术进行了全面回顾。它评估了各种传感器&#xff08;如相机、LiDAR、雷达&#xff09;的能力和技术性能&#xff0c;并讨论了多传感…

c++11特性(详细)

文章目录 前言一、C11介绍二、列表初始化1.{}初始化2.initializer_list 三、auto与decltype四、STL中变化五、右值引用六.C中关于类的新功能七.可变参数模板八.lambda表达式总结 前言 在本篇文章&#xff0c;我们将会详细介绍一下C11新增的一些特性&#xff0c;其中最重要的是…

有1,2,3,4这四个数字,能组成多少个互不相同且无重复数字的三个数?分别是什么?

有1,2,3,4这四个数字&#xff0c;能组成多少个互不相同且无重复数字的三个数&#xff1f;分别是什么&#xff1f; 提示&#xff1a;123&#xff0c;321就是符合要求&#xff0c;数字既不相同&#xff0c;而且每个数字的个十百位也不重复&#xff1b;而121,212就不行&#xff0c…

Facebook海外三不限企业广告账户-Facebook的ROI是什么?

1. 什么是ROI&#xff1f; ROI是指投资回报率&#xff08;Return on Investment&#xff09;&#xff0c;是衡量投资效益的一种指标。在市场营销领域&#xff0c;ROI是一个非常重要的概念&#xff0c;用于衡量营销活动的效果和价值。它通常用于评估一项投资的效益&#xff0c;即…