【问题标题】:How to create dynamic form input fields in React with ANTd如何使用 ANTd 在 React 中创建动态表单输入字段
【发布时间】:2021-05-01 22:25:08
【问题描述】:

代码沙盒链接: https://codesandbox.io/s/compassionate-sanderson-1m8nv?file=/src/App.js

我无法找到有关此主题的太多信息。以下是我想要实现的目标:

我希望用户能够编辑数据库中已存在的采购订单的一些详细信息,然后使用表单重新提交采购订单。原始采购订单的详细信息应显示在表单输入字段中,用户可以直接通过这些字段更改它们然后提交。

我不精通网络开发,所以请多多包涵。

我希望最终的表单对象如下所示:

{
    po_number:"123abc",
    carrier:"Fastway",
    items: [{
                item_code:"dnh75n",
                quantity:"10",
                special_requirements:"Add picture of happy dog"
            },
            {
                item_code:"456def",
                quantity:"4",
                special_requirements:"Do not include lids"
            }
        ]
}

生成的表单输入字段的数量将取决于采购订单中有多少商品。我在下面创建了一个简单的 React 组件来演示我想要做什么。或者只是签出上面的代码沙箱链接。任何帮助,将不胜感激。我什至找不到有关如何对 ANTd 表单项目进行分组以在采购订单中创建项目数组的信息。我在他们的网站上看到了很多动态表单示例,但我想根据采购订单中预先存在的项目创建表单,而不是添加带有用户输入的字段。

import { Form, Input, Button } from 'antd';

//This is the order that already exists
const order = {
    po_number:"123abc",
    carrier:"Fastway",
    items: [{
                item_code:"dnh75n",
                quantity:"10",
                special_requirements:"Add picture of happy dog"
            },
            {
                item_code:"456def",
                quantity:"4",
                special_requirements:"Do not include lids"
            }
        ]
};


const GroupForm = () => {

    const onFinish = values => {
        console.log(values);
    }
    

    //Create form fields based off how many items are in the order
    const itemInputs = order.items.map(item => {
        return (
            <div>
                <b>Item{" " + item.item_code}</b>
                <Form.Item name={item.item_code + "_quantity"} label="quantity">
                    <Input defaultValue={item.quantity} style={{width: "500px"}} />
                </Form.Item>

                <Form.Item name={item.item_code + "_requirements"} label="speacial requirements">
                    <Input defaultValue={item.special_requirements}  style={{width: "500px"}} />
                </Form.Item>
            </div>
        );
    });

    return(
        <div>
            <Form onFinish={onFinish}>
                <b>{"Order " + order.po_number}</b>
                
                <Form.Item name="carrier" label="carrier">
                    <Input defaultValue={order.carrier} style={{width: "500px"}} />
                </Form.Item>

                <b>Order Items</b>

                {itemInputs}

                <Form.Item>
                    <Button type="primary" htmlType="submit"> Change Details </Button>
                </Form.Item>
            </Form>
        </div>
    );
}

export default GroupForm;

【问题讨论】:

    标签: javascript reactjs forms antd


    【解决方案1】:

    如果您使用的是 antd 版本 4.9.0+,则可以利用 Form.List 上的 initialValue 属性。这允许您在数组的表单项上设置初始值。或者,您可以在Form 上设置initialValues 属性。这是使用前一种方法的最小可行示例。

    import { Form, Input, Button, Space } from "antd";
    import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
    import React from "react";
    
    //Basic Idea
    /* 
        I want the user to be able to edit some details of a purchase order that already exists in the database,
        then resubmit the order with a form.
        The details of the purchase order should be orginally displayed in the form input fields,
        and the user can change them directly via those fields. 
    */
    
    //This is the order that already exists
    const order = {
      po_number: "123abc",
      carrier: "Fastway",
      items: [
        {
          item_code: "dnh75n",
          quantity: "10",
          special_requirements: "Add picture of happy dog"
        },
        {
          item_code: "456def",
          quantity: "4",
          special_requirements: "Do not include lids"
        }
      ]
    };
    
    const GroupForm = () => {
      const onFinish = (values) => {
        console.log(values);
      };
    
      //Create form fields based off how many items are in the order
      const itemInputs = order.items.map((item) => {
        return {
          item_code: item.item_code,
          quantity: item.quantity,
          special_requirements: item.special_requirements
        };
      });
    
      return (
        <div>
          <Form onFinish={onFinish}>
            <b>{"Order " + order.po_number}</b>
    
            <Form.Item name="carrier" label="carrier" initialValue={order.carrier}>
              <Input style={{ width: "500px" }} />
            </Form.Item>
            <Form.Item
              name="po_number"
              label="PO number"
              initialValue={order.po_number}
              hidden
            >
              <Input />
            </Form.Item>
    
            <b>Order Items</b>
    
            <Form.List name="items" initialValue={itemInputs}>
              {(fields, { add, remove }) => (
                <>
                  {fields.map((field) => (
                    <Space
                      key={field.key}
                      style={{ display: "flex", marginBottom: 8 }}
                      align="baseline"
                    >
                      <Form.Item
                        {...field}
                        name={[field.name, "item_code"]}
                        fieldKey={[field.fieldKey, "item_code"]}
                      >
                        <Input placeholder="Item Code" />
                      </Form.Item>
                      <Form.Item
                        {...field}
                        name={[field.name, "quantity"]}
                        fieldKey={[field.fieldKey, "quantity"]}
                      >
                        <Input placeholder="Quantity" />
                      </Form.Item>
                      <Form.Item
                        {...field}
                        name={[field.name, "special_requirements"]}
                        fieldKey={[field.fieldKey, "special_requirements"]}
                      >
                        <Input placeholder="Quantity" />
                      </Form.Item>
                      <MinusCircleOutlined onClick={() => remove(field.name)} />
                    </Space>
                  ))}
                  <Form.Item>
                    <Button
                      type="dashed"
                      onClick={() => add()}
                      block
                      icon={<PlusOutlined />}
                    >
                      Add item
                    </Button>
                  </Form.Item>
                </>
              )}
            </Form.List>
    
            <Form.Item>
              <Button type="primary" htmlType="submit">
                {" "}
                Change Details{" "}
              </Button>
            </Form.Item>
          </Form>
        </div>
      );
    };
    
    export default GroupForm;
    
    // I want to submit a form object that looks like this. E.g.
    // This is what 'onFinish' should display in the console
    /*
    
    {
        po_number:"123abc",
        carrier:"Fastway",
        items: [{
                    item_code:"dnh75n",
                    quantity:"10",
                    special_requirements:"Add picture of happy dog"
                },
                {
                    item_code:"456def",
                    quantity:"4",
                    special_requirements:"Do not include lids"
                }
            ]
    }
    
    */
    

    DEMO

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      • 2019-08-23
      • 2018-10-27
      • 2016-07-30
      相关资源
      最近更新 更多