Archit Sandesara
Archit Sandesara

Reputation: 655

How to iteratively add Form.Item in Form.Item in ant design Form

     const [selectedCompanyId, setSelectedCompanyId] = useState(undefined);
     const [selectedProducts, setSelectedProducts] = useState([]);

      const { Option } = Select;
      const [form] = Form.useForm();
      const handleFormValuesChange = changedValues => {
        const formFieldName = Object.keys(changedValues)[0];
        if (formFieldName === "companyId") {
          setSelectedCompanyId(changedValues[formFieldName]);
          setSelectedProducts([]);
          form.setFieldsValue({ products: undefined }); //reset product selection
        }
        if (formFieldName === "products") {
          setSelectedProducts(changedValues[formFieldName]);
        }
      };

        <Form
            layout="vertical"
            size="medium"
            form={form}
            className="teste-form"
            requiredMark={false}
            onFinish={onFinish}
            onValuesChange={handleFormValuesChange}
          >
            <Form.Item
                  label="Company/Customer"
                  rules={[
                    { required: true, message: "Please select Company!" }
                  ]}
                  name="companyId"
                >
                  <Select style={{ width: "50%" }} name="companyId">
                    {users.map((user, index) => {
                      return (
                        <Option key={index} value={user.companyID}>
                          {user.companyName}
                        </Option>
                      );
                    })}
                  </Select>
                </Form.Item>
   <Form.Item
                  label="Products"
                  name="products"
                  rules={[
                    { required: true, message: "Please select Products!" }
                  ]}
                >
                  <Select mode="multiple" allowClear style={{ width: "70%" }}>
                    {products
                      .filter(
                        product => product.companyId === selectedCompanyId
                      )
                      .map(product => (
                        <Option key={product.id} value={product.id}>
                          {product.productName}
                        </Option>
                      ))}
                  </Select>
                </Form.Item>
           <Form.Item
                  label="Price Map"
                  name="priceMap"
                  rules={[{ required: true, message: "Please input Prices!" }]}
                >
                  {selectedProducts.forEach(productId => {
                    products.forEach(product => {
                      if (product.id === productId) {
                        return (
                          <Form.Item
                            label={product.type}
                            name={product.priceId}
                            style={{ width: "50%" }}
                            rules={[
                              { required: true, message: "Please input price!" }
                            ]}
                            initialValue={product.price}
                          >
                            {console.log("Inside form.item")}
                            <Input />
                          </Form.Item>
                        );
                      }
                    });
                  })} 
                </Form.Item>
          </Form>



I am trying to achieve dynamically add <Form.Item> in Price Map element changes according to the Product onChange selection.

I have specified <Form.Item label="Products" name="products"> and inside this I am checking condition and adding <Form.Item> iteratively.

By checking console.log() conditions in <Form.Item label="Products" name="products"> </Form.Item> are getting true but the UI doesn't show the iteratively added <Form.Item>.

I am really new to ant design and not able to figure out how to add Form.Item dynamically.

Here, users and products are json as below.

users: 

[{
companyID: 2
companyName: "TEST1"
},{
companyID: 7
companyName: "TEST2"
}]

products:

[{
companyId: 2,
id: 1,
type:"PEN",
priceId:2,
productName: "TESTProduct1"
},{
companyId: 7,
productName: "TESTProduct2",
type:"PENCIL",
priceId:3,
id: 2
},{
companyId: 7,
id: 3,
type:"ERASER",
priceId:4,
productName: "TESTProduct3"
},{
companyId: 7,
id: 4,
type:"SHARPNER",
priceId:5,
productName: "TESTProduct4"
}]

Upvotes: 1

Views: 4557

Answers (1)

Jacob
Jacob

Reputation: 78880

forEach is used to procedurably loop through an Array. It is not used to build expressions. React element expressions are what you want to return from your render functions. forEach returns undefined.

<Form.Item
  label="Price Map"
  name="priceMap"
  rules={[{ required: true, message: "Please input Prices!" }]}
>
  {selectedProducts.flatMap(productId => products
    .filter(product => product.id === productId)
    .map(product => (
      <Form.Item
        label={product.type}
        name={product.priceId}
        style={{ width: "50%" }}
        rules={[
          { required: true, message: "Please input price!" }
        ]}
        initialValue={product.price}
      >
        {console.log("Inside form.item")}
        <Input />
      </Form.Item>
    ))
  )}
</Form.Item>

Upvotes: 2

Related Questions