在react antd中动态生成多个 form表单组,包括一个动态添加/删除表单项的功能和一个提交表单的功能

这篇具有很好参考价值的文章主要介绍了在react antd中动态生成多个 form表单组,包括一个动态添加/删除表单项的功能和一个提交表单的功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在这个示例中,我们首先使用 Form.useForm() 创建一个表单实例。接着,我们使用 Form.List 组件来动态生成多个表单项。在 Form.List 组件中,我们使用 fields.map 方法循环渲染每个表单项,并使用 Form.Item 组件包裹每个表单项。在 Form.Item 组件中,我们使用 label 属性指定标签,使用 name 属性指定表单项的名称,使用 rules 属性指定验证规则。在输入框中,我们使用 placeholder 属性来指定占位文本。 在每个表单项的最后,我们使用 Button 组件来实现删除表单项的功能。在表单的最后,我们使用 Button 组件来实现提交表单的功能。当用户点击 Add field 按钮时,将会调用 add 方法,动态添加一个新的表单项。当用户提交表单时,将会调用 onFinish 方法,打印所有表单项的内容。 最后,我们在 index.js 文件中渲染 DynamicForm 组件:

示例:

接收传入的值为

const [formData, setFormData] = useState([ { cpu: 1, gpu: 3, memory: 1, frequency: 'week', day: 1, startTimeFormat: '00:00:00', endTimeFormat: '02:00:00', }, { cpu: 2, gpu: 4, memory: 1, frequency: 'day', day: 1, startTimeFormat: '00:00:00', endTimeFormat: '02:00:00', }, ]);

函数组件:

import React, { useState , useEffect,forwardRef, useImperativeHandle} from 'react';
import {
  Form, Input,
  Button,
  Table,
  message,
  InputNumber,
  Spin, Radio,
  Modal,
  Card,
  Row,
  Col, TimePicker,
  Select,
} from 'antd';
import moment from "moment";

import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
const { Option } = Select;
import styles from "./index.module.less";

const TimescrollTemplate = [
  { value: 'month', name: '月' },
  { value: 'week', name: '周' },
  { value: 'day', name: '天' },
]

function FormItem({ formItem, delShow, index, onChange, onDelete }) {
  const formatTime = (time) => {
    if (!time) {
      return '00:00:00';
    }
    const hours = time.hours().toString().padStart(2, '0');
    const minutes = time.minutes().toString().padStart(2, '0');
    const seconds = time.seconds().toString().padStart(2, '0');
    return `${hours}:${minutes}:${seconds}`;
  };
  const handleInputChange = (index, name, value) => {
    console.log(index, name, value, "index, name, value")
    if (name, value) {
      if (name == "startTimeFormat") {
        // const formattedTime = formatTime(value);
        const [startTime, endTime] = value
        console.log(startTime, endTime, "startTime, endTime")
        onChange(index, "startTimeFormat", formatTime(startTime));
        onChange(index, "endTimeFormat", formatTime(endTime));
      } else {
        onChange(index, name, value);
      }
    }
  };
  return (
    <>
      <Row gutter={[0, 24]} className={styles.listBody}>
        <Col className="gutter-row" span={10}>
          <Row gutter={[0, 24]}  >

            <Col className="gutter-row" style={{
              textAlign: "left",
              lineHeight: '32px',

            }} span={8}>
              <div className={styles.rowTie}>CPU(核)</div>

              <InputNumber min={0} style={{ maxwidth: 160, marginLeft: 24, borderRadius: 2 }} value={formItem.cpu}
                name="cpu"
                onChange={(newValue) => handleInputChange(index, 'cpu', newValue)}
              />

            </Col>
            <Col className="gutter-row" style={{
              lineHeight: '32px',
              textAlign: "left"
            }} span={8}>
              <div className={styles.rowTie}>GPU(个)</div>
              <InputNumber
                name="gpu"
                value={formItem.gpu}
                onChange={(newValue) => handleInputChange(index, 'gpu', newValue)}
                min={0} style={{ maxwidth: 160, marginLeft: 24, borderRadius: 2 }} />

            </Col>
            <Col className="gutter-row" style={{
              lineHeight: '32px',
              textAlign: "left"
            }} span={8}>
              <div className={styles.rowTie}>内存(G)</div>

              <InputNumber
                name="memory"
                value={formItem.memory}
                onChange={(newValue) => handleInputChange(index, 'memory', newValue)}
                min={0} style={{ maxwidth: 160, marginLeft: 24, borderRadius: 2 }} />

            </Col>
          </Row>
        </Col>
        <Col className="gutter-row" span={14}>
          <div style={{
            textAlign: "left",
            fontWeight: 500,
            marginLeft: 24,
            lineHeight: "32px"
          }}>时间段</div>
          <div style={{
            marginLeft: 24, display: "flex", lineHeight: "32px", color: "#999"
          }}>
            在每

            <Select
              placeholder="天"
              name="frequency"
              value={formItem.frequency}
              onChange={(newValue) => handleInputChange(index, 'frequency', newValue)}

              style={{ borderRadius: 2, marginLeft: 5 }}
            >
              {(
                TimescrollTemplate || []).map((item) => (
                  <Select.Option key={item.value} value={item.value}>
                    {item.name}
                  </Select.Option>
                ))}
            </Select>


            <Select
              type="number"
              name="day"
              value={formItem.day}
              onChange={(newValue) => handleInputChange(index, 'day', newValue)}
              mode="tags"
              placeholder="请选择执行日"
              style={{ overflowY: 'auto', width: 200,maxHeight:32, marginLeft: 10 }}
            >
              {Array.from({ length: 31 }, (_, index) => index + 1).map((item,index) => (
                <Select.Option key={item.index} value={item}>
                  {item}
                </Select.Option>
              ))}

            </Select>
            <TimePicker.RangePicker
              name="startTimeFormat"
              onChange={(newValue) => handleInputChange(index, 'startTimeFormat', newValue)}
              size="small"
              value={
                // moment(formItem.startTimeFormat, 'HH:mm:ss')
                [moment(formItem.startTimeFormat, 'HH:mm:ss'), moment(formItem.endTimeFormat, 'HH:mm:ss')]
              }
              style={{ marginLeft: 10, width: 200 }} />

            {/* <TimePicker
              name="endTimeFormat"
              size="small"
              value={moment(formItem.endTimeFormat, 'HH:mm:ss')}
              onChange={(newValue) => handleInputChange(index, 'endTimeFormat', newValue)}
              style={{ marginLeft: 10, width: 200 }} /> */}
            {delShow &&
              <div
                style={{
                  marginLeft: 5, position: 'absolute',
                  right: '24px',
                  top: '27px'
                }}
              >
                <a onClick={() => onDelete(index)} >删除</a>
              </div>
            }
          </div>
        </Col>

      </Row>

    </>

  );
}
const DynamicForm =  forwardRef(({ onSubmit, value = [] }, ref) => {
  console.log(value,"value")

  const [formData, setFormData] = useState(value);
  console.log(formData,"formData")
  useEffect(() => {
    setFormData(value);
  }, [value]);
  const handleFormSubmit = (event) => {
    event.preventDefault();
    console.log(formData); // 打印表单数据
    onSubmit(formData);
  };
  useImperativeHandle(ref, () => ({ handleFormSubmit }));
  const handleFormItemChange = (index, name, value) => {
    console.log(index, name, value, "index, name, value")
    setFormData((prevFormData) => {
      const newFormData = [...prevFormData];
      newFormData[index][name] = value;
      return newFormData;
    });
  };
  const handleFormItemDelete = (index) => {
    setFormData((prevFormData) => {
      const newFormData = [...prevFormData];
      newFormData.splice(index, 1);
      return newFormData;
    });
  };
  const handleFormAdd = () => {
    setFormData((prevFormData) => [
      ...prevFormData,
      {
        cpu: 1,
        gpu: 1,
        memory: 1,
        frequency: 'month',
        day: 1,
        startTimeFormat: '00:00:00',
        endTimeFormat: '00:00:00',
      },
    ]);
  };
  return (
    <form onSubmit={handleFormSubmit}>
      {formData.map((formItem, index) => (
        <FormItem
          key={index}
          formItem={formItem}
          index={index}
          delShow={formData.length > 1}
          onChange={handleFormItemChange}
          onDelete={handleFormItemDelete}
        />
      ))}

      <div >
        <Button style={{ textAlign: 'center', width: 400 }}   type="primary" onClick={handleFormAdd} icon={<PlusOutlined />}>
        添加资源评估
        </Button>
      </div>
      {/* <button type="submit">提交</button> */}
    </form>
  );
});
export default DynamicForm;

 文章来源地址https://www.toymoban.com/news/detail-616103.html

到了这里,关于在react antd中动态生成多个 form表单组,包括一个动态添加/删除表单项的功能和一个提交表单的功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Element-UI可以动态生成的form表单

    此form表单每一项绑定的值组成一个对象,对象叠加组成了一个对象数组,循环对象数组生成form的表单项。当点击新增一项时,其实就是给form表单对象数组添加一个对象,删除则反之。值得注意的是,由于动态表单得到的是一个对象数组,但我们需要的是表单的值组成的对象

    2024年02月11日
    浏览(35)
  • vue3 antd项目实战——Form表单的重置【使用resetFields()重置form表单数据、清空输入框】

    文章内容 文章链接 Form表单 提交和校验 https://blog.csdn.net/XSL_HR/article/details/128495087?spm=1001.2014.3001.5501 Form表单的 嵌套使用 https://blog.csdn.net/XSL_HR/article/details/128488913?spm=1001.2014.3001.5501 Form表单的 动态校验规则 https://blog.csdn.net/XSL_HR/article/details/128437275?spm=1001.2014.3001.5501 往期文章

    2024年02月02日
    浏览(38)
  • ant.design(简称antd)中Form表单组件提交表单、表单数据效验、表单自定义效验、表单布局集合

            ant.design(简称antd)现在我们使用较为广泛,web端中后台表单使用非常广泛,此遍文章集合了表单日常用法及使用注意事项。         下图是UI目标样式图                           1、以下是一个组件,首先引入ant相关依赖,在引入react相关依赖,主要使用了For

    2024年02月13日
    浏览(36)
  • 【Antd】antd form表单的rules文案无法跟随状态重渲染的原因及解决办法

    问题背景 我有两个表单项,当我选择出库类型,调用onChange改变inOutType 状态,这时候发现这句代码不生效: 示例代码 原因 antd官方为了尽量少造成多余的渲染,把这个主动权交由开发者自己来实现,适配更多场景,得到相对优秀的渲染性能 解决代码

    2024年02月13日
    浏览(24)
  • vue3 antd项目实战——Form表单的重置与清空【resetFields重置表单未生效(手写重置函数)】

    文章内容 文章链接 Form表单 提交和校验 https://blog.csdn.net/XSL_HR/article/details/128495087?spm=1001.2014.3001.5501 Form表单的 嵌套使用 https://blog.csdn.net/XSL_HR/article/details/128488913?spm=1001.2014.3001.5501 Form表单的 动态校验规则 https://blog.csdn.net/XSL_HR/article/details/128437275?spm=1001.2014.3001.5501 From表单的

    2024年02月02日
    浏览(40)
  • React Antd form.getFieldsValue() 和 form.getFieldsValue(true) 有区别吗?

    突然发现 antd 的 getFieldsValue()是可以传一个 true 参数的,如题,React Antd form.getFieldsValue() 和 form.getFieldsValue(true) 有区别吗? 确实不一样 getFieldsValue 提供了多种重载方法: getFieldsValue(nameList?: true | NamePath[], filterFunc?: FilterFunc) 当不提供 nameList 时,返回所有注册字段,这也包含

    2024年02月11日
    浏览(25)
  • uniapp collapse动态生成多个折叠面板手动展开收起(包括uni-ui版)

    官方文档没有暴露出相关api,那就看看组件源码。 以下示例均通过  vue-cli  创建的  uni-app  h5 项目 源码 node_modulesuview-uicomponentsu-collapse-itemu-collapse-item.vue 这个方法是用来改变折叠面板子组件收起还是展开的,根据改变 isShow 的值来实现 方法 源码 node_modules@dcloudiouni-ui

    2024年02月06日
    浏览(45)
  • form 校验多个表单

    有的时候,表单需要拆开多个,这时候就需要校验多个表单  

    2024年02月16日
    浏览(31)
  • 【react框架】结合antd做表单组件的一些心得记录

    作为一个前端最常遇见的需求场景就是写表单、写表格。写多了会逐渐的积累一些开发心得,此文章根据我使用vue和react的经验记录了一些东西,抛砖引玉的给大家看看。 举例react项目,在做表单的很多时候,我都是从antd上把其中一个form组件例子复制下来,然后再看看提供了

    2024年02月07日
    浏览(84)
  • Element 多个Form表单 同时验证

    在一个页面中需要实现两个Form表单,并在页面提交时需要对两个Form表单进行校验,两个表单都校验成功时才能提交 所用技术栈:Vue2+Element UI 注意项: 两个form表单,每个表单上都设置单独的model和ref,不能同时使用,否则每个表单上的校验提示会失效 最后,👏👏 😀😀😀

    2024年02月07日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包