Reputation: 887
I have a dynamic Antd form where I can enter menu elements. The user can add, remove and reorder menu elements. The dynamic fields work fine, but I have a radio button for each dynamic element indicating that the corresponding menu element is an external URL or an internal page. I need to display different input elements if the user chooses URL or internal page. I tried the method listed in the Antd documentation, but it is for static fields and it doesn't seem to be working for dynamic elements.
My code so far is:
<Form.List name={"menuTree"}>
{(fields, { add, remove }) => (
<>
{fields.map((field, index) => (
<Row id={"menu-row-" + index} key={index}>
<Col span={8}>
<Form.Item label="Title" name={[field.name, "title"]} key={"title" + index + Math.random()}>
<Input />
</Form.Item>
</Col>
<Col span={4}>
<Form.Item label="Type" name={[field.name, "type"]}>
<Radio.Group>
<Radio value={"link"}>URL</Radio>
<Radio value={"page"}>Page</Radio>
</Radio.Group>
</Form.Item>
</Col>
<Col span={9}>
<Form.Item
// label="URL"
// name={[field.name, "url"]}
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}>
{({ getFieldValue }) => {
return getFieldValue("type") === "link" ? (
<Form.Item name={[field.name, "url"]} label="URL">
<Input />
</Form.Item>
) : (
<Form.Item name={[field.name, "page"]} label="Page">
<Input />
</Form.Item>
)
}}
<Input />
</Form.Item>
</Col>
<Col span={2}>
<Form.Item>
<Button htmlType="button" onClick={() => moveUp(index)}>
<CaretUpOutlined />
</Button>
<Button htmlType="button" onClick={() => moveDown(index)}>
<CaretDownOutlined />
</Button>
</Form.Item>
</Col>
<Col span={1}>
<Button htmlType="button" onClick={() => removeMenuItem(index)}>
<MinusOutlined />
</Button>
</Col>
</Row>
))}
<Button type="dashed" onClick={() => addMenuItem()} block icon={<PlusOutlined />}>
Add menu item
</Button>
</>
)}
</Form.List>
How can I achieve to change the input on a per line basis whenever the user changes the value of the radio button?
Upvotes: 0
Views: 1825
Reputation: 1566
You are trying to get type
value with wrong name path. getFieldValue
expects the complete path when you want to get any value.
You form list name is menuTree
. Since it's a list, your namepath will look like this:
getFieldValue(['menuTree', field.name, 'type'])
<Form>
<Form.List name={'menuTree'}>
{(fields, { add, remove }) => (
<>
{fields.map((field, index) => (
<Row id={'menu-row-' + index} key={index}>
<Col span={8}>
<Form.Item label='Title' name={[field.name, 'title']} key={'title' + index + Math.random()}>
<Input />
</Form.Item>
</Col>
<Col span={4}>
<Form.Item label='Type' name={[field.name, 'type']}>
<Radio.Group>
<Radio value={'link'}>URL</Radio>
<Radio value={'page'}>Page</Radio>
</Radio.Group>
</Form.Item>
</Col>
<Col span={9}>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) =>
prevValues?.menuTree?.[field.name]?.type !== currentValues?.menuTree?.[field.name]?.type
}
>
{({ getFieldValue }) => {
return (
<>
{getFieldValue(['menuTree', field.name, 'type']) === 'link' ? (
<Form.Item name={[field.name, 'url']} label='URL'>
<Input />
</Form.Item>
) : (
<Form.Item name={[field.name, 'page']} label='Page'>
<Input />
</Form.Item>
)}
</>
);
}}
</Form.Item>
</Col>
<Col span={2}>
<Form.Item>
<Button htmlType='button' onClick={() => {}}>
<CaretUpOutlined />
</Button>
<Button htmlType='button' onClick={() => {}}>
<CaretDownOutlined />
</Button>
</Form.Item>
</Col>
<Col span={1}>
<Button htmlType='button' onClick={() => remove(field.name)}>
<MinusOutlined />
</Button>
</Col>
</Row>
))}
<Button type='dashed' onClick={() => add()} block icon={<PlusOutlined />}>
Add menu item
</Button>
</>
)}
</Form.List>
</Form>
Upvotes: 1