Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ANTD dynamic form - initial values

I have issue with setting initial values for antd dynamic form. Is there any way how to init values in dynamic for. It requires registered field using getFieldDecorator. But for dynamic fields, that field is not registered before.

I am getting this error: You cannot set field before registering it.

code: https://codesandbox.io/s/jnx3p1nz5

import React from "react";
import { Select, Icon, Button, Form, Input } from "antd";

const FormItem = Form.Item;
const TextArea = Input.TextArea;
const Option = Select.Option;

const SELECT = ['opt1', 'opt2'];

class TestForm extends React.Component {
  state = {
    listKeys: [0]
  };

  componentDidMount() {
    const {
      form: { setFieldsValue }
    } = this.props;


    // WORK
    // setFieldsValue({
    //   name: 'test',
    // });

    // setFieldsValue({
    //   name: 'test',
    //   list: [
    //     {
    //       sub1: 'test1',
    //       sub2: 'test2',
    //     }
    //   ]
    // });

    // !!!!!!!!!!!! NOT WORK
    // setFieldsValue({
    //   name: 'test',
    //   list: [
    //     {
    //       sub1: 'test1',
    //       sub2: 'opt2'
    //     },
    //     {
    //       sub1: 'test11',
    //       sub2: 'opt1'
    //     }
    //   ]
    // });

    setFieldsValue({
      name: 'test',
      list: [
        {
          sub1: 'test1',
          sub2: 'opt2',
          opt2sub: 'bla',
        },
        {
          sub1: 'test11',
          sub2: 'opt1'
        },
        {
          sub1: 'test3',
          sub2: 'opt2',
          opt2sub: 'bla',
        },
      ]
    });
  }

  remove = k => {
    const { listKeys } = this.state;

    if (listKeys.length === 1) {
      return;
    }

    this.setState({
      listKeys: listKeys.filter(key => key !== k)
    });
  };

  add = () => {
    const { listKeys } = this.state;

    this.setState({
      listKeys: [...listKeys, listKeys.length]
    });
  };

  render() {
    const {
      form: { getFieldDecorator, getFieldValue }
    } = this.props;
    const { listKeys } = this.state;

    return (
      <Form onSubmit={this.handleSubmit}>
        <FormItem label="Name">
          {getFieldDecorator("name")(<Input placeholder="name" />)}
        </FormItem>
        {listKeys.map((key, index) => {
          const type = getFieldValue(`list[${key}].sub2`);

          return (
            <div key={key}>
              <FormItem label="Sub1">
                {getFieldDecorator(`list[${key}].sub1`)(
                  <Input placeholder="Sub1" />
                )}
              </FormItem>
              <FormItem label="Sub2">
                {getFieldDecorator(`list[${key}].sub2`,{
                  initialValue: 'opt1'
                })(
                  <Select>
                    {SELECT.map(item => <Option key={item} value={item}>{item}</Option> )}
                  </Select>
                )}
              </FormItem>
              {type === 'opt2' && (
                <FormItem label="opt2sub">
                  {getFieldDecorator(`list[${key}].opt2sub`)(
                    <Input placeholder="opt2sub" />
                  )}
                </FormItem>
              )}
              {index > 0 && (
                <Icon
                  className="dynamic-delete-button"
                  type="minus-circle-o"
                  onClick={() => this.remove(key)}
                />
              )}
            </div>
          );
        })}
        <FormItem>
          <Button type="dashed" onClick={this.add}>
            <Icon type="plus" />Add field
          </Button>
        </FormItem>
        <FormItem>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </FormItem>
      </Form>
    );
  }
}

export default Form.create()(TestForm);
like image 301
Dawe Avatar asked Aug 13 '26 03:08

Dawe


1 Answers

You can use forceRender={true} in the prop that holding the form to render it. I had a form inside drawer. For that i had same error. Which I used forceRender={true} in drawer prop. So whichever holding the form, you need to render that using forceRender.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!