lony
lony

Reputation: 7799

Ant Design how to handle Form.List accessing values from underlaying data structure?

I try to grasp Form.List from Ant Design. I already figured out that it contains FieldData[], where each element contains name, key, fieldKey but I do not know how to use this to access its values. I tried to solve the following two use cases based on a code sample I found in another question:

Condensed from the above codesandbox example I have the following Form and Table code, leaving both TODO's which I'm not able to solve. Can you help me out?

If in general, you have knowledge about Form.List, this would also help a lot? For example explaining, why I need it for dynamic forms and what it is doing internally and for the component?

Any help would be appreciated, thanks a lot.

import { Button, Form, Row, notification, Table, InputNumber } from "antd";
import React, { useState } from "react";
import { useForm } from "antd/lib/form/util";

const TestForm: React.FC = () => {
 const [data, setData] = useState({ users: [] });
 const [form] = useForm();
 const [editingIndex, setEditingIndex] = useState<number | undefined>(
   undefined
   );

 const onFinish = (values: any) => {
   notification.success({
       message: "Submit",
       description: `Received values of form: ${JSON.stringify(values)}`
   });
   setData(values);
   };

 return (
  <Form
  form={form}
  name="dynamic_form_item"
  onFinish={onFinish}
  initialValues={data}
  >
   <Form.List name="users">
    {(users, { add, remove }) => (
     <Table
      dataSource={users}
      pagination={false}
      footer={fields => {
       // TODO calculate age sum from fields
       return (
           <Button>Add User</Button>
       );
      }}
      >
       <Table.Column
           dataIndex={"age"}
           title={"Age"}
           width={125}
           sorter={() => {
             // TODO build something to sort here sorter: (a, b) => a.weight - b.weight,
             return 0;
           }}
           render={(value, row, index) => {
            return (
             <EditableFormItem
                 name={[index, "age"]}
                 editing={index === editingIndex}
                 className={"ant-form-item-no-bottom-margin"}
                 >
                 <InputNumber placeholder="age" min={0} max={150} />
             </EditableFormItem>
            );
           }}
       />
      </Table>
     )}
    </Form.List>
   </Form>
  )};

export default TestForm;

Upvotes: 5

Views: 6243

Answers (1)

Felix K.
Felix K.

Reputation: 15683

The trick is to use the whole NamePath to access the field's value.

  • Your <Form.List> has the name attribute "users".
  • When you map the fields: Field[] (in your case called users), ant maps each field's index to the name parameter.

Combine this information with the field's actual input name and you get the field NamePath to access the form entry's value via form.getFieldValue():

form.getFieldValue(["users", name, "age"])

Upvotes: 2

Related Questions