Sai Krishnadas
Sai Krishnadas

Reputation: 3419

how to populate input field when value of select is changed using Antd Form?

I need to change the value of the input field to whatever value of the select field has changed. If "Fire" is selected in the select field, then the input field needs to change to "Fire" as well. This works when using the value in the input field and assigning the state of select to it.

Working Code:

const [type, setType] = React.useState("");

 <Select
          style={{
            width: 120
          }}
          onChange={(value) => setType(value)}
        >
          <Option value="fire">Fire</Option>
          <Option value="water">Water</Option>
          <Option value="wind">Wind</Option>
 </Select>
<Input
  style={{
    width: 120
  }}
  placeholder="Enter Type"
  value={type}
/>

The above code works, but using inside a Form, it doesn't.

Code:

const Demo = () => {
  const [type, setType] = React.useState("");
  return (
    <Form onFinish={onSubmit}>
      <Form.Item name="floorType">
        <Select
          style={{
            width: 120
          }}
          onChange={(value) => setType(value)}
        >
          <Option value="fire">Fire</Option>
          <Option value="water">Water</Option>
          <Option value="wind">Wind</Option>
        </Select>
      </Form.Item>

      <Form.Item name="floorName">
        <Input
          style={{
            width: 120
          }}
          placeholder="Enter Type"
          value={type}
        />
      </Form.Item>

      <Form.Item>
        <Button
          type="primary"
          htmlType="submit"
          style={{
            width: 120
          }}
        >
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
};

The value isn't set in the input field.

UI Library used : Antd https://ant.design/components/form/

Codesandbox link : https://codesandbox.io/s/basic-usage-antd-4-21-6-forked-ckxgsy?file=/demo.js

Upvotes: 0

Views: 2329

Answers (1)

Doc
Doc

Reputation: 681

Fixed fork

I based this fix on the Antd Form > Form Methods example, which shows how to update a form field when another one changes.


The problem seems to be you're using Input>value instead of letting the Antd Form handle the form state.

The problem arises when adding Form.Item>name, because in this way the Form itself handles the child input value using a hidden state object where the keys are the Form.Item names and the initial values are the ones you can optionally define inside Form>initialValues prop.

So, if you want to avoid having the form manage the state, you should also avoid using Form.Item>name prop and manage all form state yourself (but missing out on many of the advantages of the Antd form). In fact this should be avoided.


Explanation of the fix

In the fork, the form manages the state, and the setFieldsValue method is used to update the floorName value (aka your Input).

Changes

  • Removed the value prop from the input

    <Input
       style={{
         width: 120
       }}
       placeholder="Enter Type"
       // Remove the prop value from the input and let the form handle it
     />
    
  • Add a form reference (using Form.useForm)

    const Demo = () => {
        // Get a form reference
        const [form] = Form.useForm();
    
        return (
         <Form
            form={form}
            ...
    
  • Update the Select onChange using the form method setFieldsValue instead of the setType setter

    <Select
       style={{
         width: 120
       }}
       onChange={(value) => {
         // Set New Form Value for Form.Item > name = 'floorName'
         form.setFieldsValue({ floorName: value }); 
         // Using the Form.Item 'name' as object key when updating
       }}
     >
    

After all, the Antd Form is an

High performance Form component with data scope management

so you shouldn't try to handle the form state yourself (especially when Form.Item>name is specified for your fields).

Upvotes: 2

Related Questions