I am creating a functionality using antd and react.js to implement dynamic form fields like below link: https://codesandbox.io/s/853qm4?file=/demo.tsx
Here initially I want the price input field to be disabled and once I select any sight value, price should automatically enabled. I have tried with onchange and useState, but in this case price textbox for all the newly added fields became disabled, and all became enable when I select a value from any one field. Can anyone help me on this?
You can check if a sight
is selected for a particular list item then make this input as enabled.
form.getFieldValue(['sights', field.name, 'sight'])
Here sights
is name of list, field.name
is index of list item.
Complete code
import React from "react";
import "./index.css";
import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
import { Button, Form, Input, Select, Space } from "antd";
const { Option } = Select;
const areas = [
{ label: "Beijing", value: "Beijing" },
{ label: "Shanghai", value: "Shanghai" }
];
const sights = {
Beijing: ["Tiananmen", "Great Wall"],
Shanghai: ["Oriental Pearl", "The Bund"]
};
type SightsKeys = keyof typeof sights;
const App: React.FC = () => {
const [form] = Form.useForm();
const onFinish = (values: any) => {
console.log("Received values of form:", values);
};
const handleChange = () => {
form.setFieldsValue({ sights: [] });
};
return (
<Form
form={form}
name="dynamic_form_complex"
onFinish={onFinish}
style={{ maxWidth: 600 }}
autoComplete="off"
>
<Form.Item
name="area"
label="Area"
rules={[{ required: true, message: "Missing area" }]}
>
<Select options={areas} onChange={handleChange} />
</Form.Item>
<Form.List name="sights">
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<Space key={field.key} align="baseline">
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) =>
prevValues.area !== curValues.area ||
prevValues.sights !== curValues.sights
}
>
{() => (
<Form.Item
{...field}
label="Sight"
name={[field.name, "sight"]}
rules={[{ required: true, message: "Missing sight" }]}
>
<Select
disabled={!form.getFieldValue("area")}
style={{ width: 130 }}
>
{(
sights[form.getFieldValue("area") as SightsKeys] || []
).map((item) => (
<Option key={item} value={item}>
{item}
</Option>
))}
</Select>
</Form.Item>
)}
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prev, cur) =>
prev?.sights[field?.name]?.sight !==
cur?.sights[field?.name]?.sight
}
>
{() => {
const disabled = !form.getFieldValue([
"sights",
field.name,
"sight"
]);
return (
<Form.Item
{...field}
label="Price"
name={[field.name, "price"]}
rules={[{ required: true, message: "Missing price" }]}
>
<Input disabled={disabled} />
</Form.Item>
);
}}
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
block
icon={<PlusOutlined />}
>
Add sights
</Button>
</Form.Item>
</>
)}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
export default App;
Hope this solves your problem