0


在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://blog.csdn.net/weixin_38791717/article/details/130101713
版权归原作者 ballelv 所有, 如有侵权,请联系我们删除。

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

还没有评论