Make-dynamic-form-with-Antd

Photo by: Diego Madrigal

I’ve been using Antd at work for a while now, it makes FE development a lot easier with it’s beatifule UI and high quality modular components.

Form component and getFieldValue

Here’s a form example.

I want to build a form with a dropdown and a text input, but need to disable the text input if dropdown was assigned with certain value.

This was what I initially wrote, but the conditional disabled text input didn’t work.

<Form>
  <Form.Item
    label="Select method"
    name="method"
    required
    rules={[
      {
        required: true,
        message: "Method is a required field."
      }
    ]}
  >
    <Select placeholder="Select a method">
      <Select.Option key="A">Method A</Select.Option>
      <Select.Option key="B">Method B</Select.Option>
      <Select.Option key="C">Method C</Select.Option>
    </Select>
  </Form.Item>
  <Form.Item
    label="Text input"
    name="text"
    shouldUpdate={(prevValues, curValues) =>
      prevValues.text !== curValues.text
    }
  >
    {({ getFieldValue }) => {
      const textFieldDisabled = getFieldValue("method") === "A";
      return (
        <Form.Item
          name="text"
          rules={[
            {
              message: "Text is a required field."
            }
          ]}
        >
          <Input disabled={textFieldDisabled}/>
        </Form.Item>
      );
    }}
  </Form.Item>
</Form>

What did I do wrong?

It’s such a silly mistake where shouldUpdate should compare the value of the field it dependent on, ie method value. Also keep an eye on the text input validation ruls if it’s a required field, make that conditional too.

Now it’s fixed and works as expected.

<Form>
  <Form.Item
    label="Select method"
    name="method"
    required
    rules={[
      {
        required: true,
        message: "Method is a required field."
      }
    ]}
  >
    <Select placeholder="Select a method">
      <Select.Option key="A">Method A</Select.Option>
      <Select.Option key="B">Method B</Select.Option>
      <Select.Option key="C">Method C</Select.Option>
    </Select>
  </Form.Item>
  <Form.Item
    label="Text input"
    shouldUpdate={(prevValues, curValues) =>
      prevValues.method !== curValues.method
    }
  >
    {({ getFieldValue }) => {
      const textFieldDisabled = getFieldValue("method") === "A";
      return (
        <Form.Item
          name="text"
          rules={[
            {
              required: !textFieldDisabled,
              message: "Text is a required field."
            }
          ]}
        >
          <Input disabled={textFieldDisabled}/>
        </Form.Item>
      );
    }}
  </Form.Item>
</Form>

  TOC