重新排序动态和表单字段



我有一个动态表单,我可以在其中添加多个表单字段。现在我想重新排序表单字段。例如,我有下面的代码,我可以添加字段为sight 1, sight 2, sight 3等各自的价格字段。现在我想把视线3移到视线1和2的中间。我如何实现一个函数来创建向上和向下移动按钮,点击,我可以向上或向下移动那一行。

下面是我的代码:
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, index) => (
<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 ${field.name + 1}`}
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)} />
<Button
style={{ marginTop: "30px" }}
onClick={() => changeOrder(index, "Up")}
block
>
Up
</Button>
<Button
style={{ marginTop: "30px" }}
onClick={() => changeOrder(index, "Down")}
block
>
Down
</Button>
</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;

Antd Form List提供move函数对列表中的项进行排序。你可以用它来对项目进行排序。move函数需要两个参数。from指数和to指数

这是完整的代码。

import React from 'react';
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, move }) => (
<>
{fields.map((field, index) => (
<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 ${field.name + 1}`}
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)} />
<Button style={{ marginTop: '30px' }} onClick={() => move(index, index - 1)} block disabled={index === 0}>
Up
</Button>
<Button
style={{ marginTop: '30px' }}
onClick={() => move(index, index + 1)}
block
disabled={index === fields.length - 1}
>
Down
</Button>
</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;

TLDR:每个项目有两个按钮,你不能UP操作到第一个项目,因为它之前没有项目。最后一项也一样(没有向下操作)。您可以根据列表长度和项目索引禁用按钮或隐藏按钮。以上代码根据项目位置禁用按钮。

最新更新