Search code examples
reactjsantd

set initalValues in nested dynamic form | Antd


I've created the sandbox below hoping someone can help me.

https://codesandbox.io/s/suspicious-leaf-cijswt?file=/src/App.js

What I need to do is basically load the ingredients array as initialValues of Form.List.

Is that possible? If yes, how?

I'd really appreciate any help.

Thanks!


Solution

  • Use initialValues prop in Form to initialize fields. Since you named your FormList as users. You can set the values like this:

    initialValues={{ users: ingredients }}
    

    Now your field looks like this:

    <Form.Item
        {...restField}
        name={[name, "first"]}
        rules={[{ required: true, message: "Missing first name" }]}
        >
            <Input placeholder="First Name" />
    </Form.Item>
    

    The most thing is the name attribute name={[name, "first"]}. In ingredients array, each object have the following keys: key, id, & amount. Suppose you want to show id & amount in each input. You specify the field path using [name, "id"]. where name presents the index of array & id is the key of object in an array. Antd will automatically get the value if it's available in that array.

    I just make few changes changes like proper naming keys,... according to the data

    Complete Code

    import { Form, Input, Button, Space, InputNumber } from 'antd';
    import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
    
    const ingredients = [
        {
            key: 0,
            name: 'Wheat Flour',
            amount: 1000
        },
        {
            key: 1,
            name: 'Sugar',
            amount: 800
        }
    ];
    
    export default function App() {
        return (
            <Space style={{ display: 'flex', margin: 36 }} align='baseline'>
                <Form
                    name='dynamic_form_nest_item'
                    onFinish={console.log}
                    autoComplete='off'
                    initialValues={{ ingredients: ingredients }}
                >
                    <Form.List name='ingredients'>
                        {(fields, { add, remove }) => (
                            <>
                                {fields.map(({ key, name, ...restField }) => (
                                    <Space key={key} style={{ display: 'flex', marginBottom: 8 }} align='baseline'>
                                        <Form.Item
                                            {...restField}
                                            name={[name, 'name']}
                                            rules={[{ required: true, message: 'Missing ingredient' }]}
                                        >
                                            <Input placeholder='Ingredient' />
                                        </Form.Item>
                                        <Form.Item
                                            {...restField}
                                            name={[name, 'amount']}
                                            rules={[{ required: true, message: 'Missing Amount' }]}
                                        >
                                            <InputNumber placeholder='Amount' />
                                        </Form.Item>
                                        <MinusCircleOutlined onClick={() => remove(name)} />
                                    </Space>
                                ))}
                                <Form.Item>
                                    <Button type='dashed' onClick={() => add()} block icon={<PlusOutlined />}>
                                        Add field
                                    </Button>
                                </Form.Item>
                            </>
                        )}
                    </Form.List>
                    <Form.Item>
                        <Button type='primary' htmlType='submit'>
                            Submit
                        </Button>
                    </Form.Item>
                </Form>
            </Space>
        );
    }