在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;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用ReactAntd编写表单的示例代码: ``` import React, { useState } from "react"; import { Form, Input, Button } from "antd"; const FormComponent = () => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const onFinish = (values) => { setLoading(true); console.log("Received values of form: ", values); // Send form data to backend }; const onFinishFailed = (errorInfo) => { console.log("Failed:", errorInfo); }; return ( <Form form={form} name="basic" initialValues={{ remember: true }} onFinish={onFinish} onFinishFailed={onFinishFailed} > <Form.Item label="Username" name="username" rules={[ { required: true, message: "Please input your username!" }, { max: 15, message: "Username should be less than 15 characters!" }, ]} > <Input /> </Form.Item> <Form.Item label="Password" name="password" rules={[ { required: true, message: "Please input your password!" }, { min: 6, message: "Password should be at least 6 characters!" }, ]} > <Input.Password /> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" loading={loading}> Submit </Button> </Form.Item> </Form> ); }; export default FormComponent; ``` 在上面的代码,我们使用了`Form`、`Input`和`Button`件来构建表单。`Form`件通过`useForm`钩子来获取`form`对象,`name`属性指定表单的名称,`initialValues`属性设置表单的初始值。`Form.Item`件用于包装每个表单项,`label`属性设置表单项的标签,`name`属性设置表单项的名称,`rules`属性设置表单项的校验规则。`Input`件用于输入文本,`Input.Password`件用于输入密码。`Button`件用于提交表单数据,`type`属性设置按钮的类型,`htmlType`属性设置按钮的提交类型,`loading`属性设置按钮是否处于加载状态。`onFinish`方法在表单提交成功后被调用,`onFinishFailed`方法在表单提交失败后被调用。我们可以在这两个方法处理表单数据的提交和校验错误的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值