ant-design/components/form/demo/form-context.md

138 lines
3.7 KiB
Markdown
Raw Normal View History

---
order: 8
title:
zh-CN: 多表单联动
en-US: Control between forms
---
## zh-CN
通过 `Form.Provider` 在表单间处理数据。本例子中Modal 的确认按钮在 Form 之外,通过 `form.submit` 方法调用表单提交功能。反之,则推荐使用 `<Button htmlType="submit" />` 调用 web 原生提交逻辑。
## en-US
Use `Form.Provider` to process data between forms. In this case, submit button is in the Modal which is out of Form. You can use `form.submit` to submit form. Besides, we recommend native `<Button htmlType="submit" />` to submit a form.
```tsx
import { Form, Input, InputNumber, Modal, Icon, Button, Avatar, Typography } from 'antd';
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
interface ModalFormProps {
visible: boolean;
onCancel: () => void;
}
const ModalForm: React.FC<ModalFormProps> = ({ visible, onCancel }) => {
const [form] = Form.useForm();
React.useEffect(() => {
form.resetFields();
}, [visible]);
const onOk = () => {
form.submit();
};
return (
<Modal title="Basic Drawer" visible={visible} onOk={onOk} onCancel={onCancel}>
<Form form={form} layout="vertical" name="userForm">
<Form.Item name="name" label="User Name" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="age" label="User Age" rules={[{ required: true }]}>
<InputNumber />
</Form.Item>
</Form>
</Modal>
);
};
const Demo = () => {
const [visible, setVisible] = React.useState(false);
const showUserModal = () => {
setVisible(true);
};
const hideUserModal = () => {
setVisible(false);
};
const onFinish = values => {
console.log('Finish:', values);
};
return (
<div>
<Form.Provider
onFormFinish={(name, { values, forms }) => {
if (name === 'userForm') {
const { basicForm } = forms;
const users = basicForm.getFieldValue('users') || [];
basicForm.setFieldsValue({ users: [...users, values] });
setVisible(false);
}
}}
>
<Form {...layout} name="basicForm" onFinish={onFinish}>
<Form.Item name="group" label="Group Name" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item
label="User List"
shouldUpdate={(prevValues, curValues) => prevValues.users !== curValues.users}
>
{({ getFieldValue }) => {
const users = getFieldValue('users') || [];
return users.length ? (
<ul>
{users.map((user, index) => (
<li key={index} className="user">
<Avatar icon="user" />
{user.name} - {user.age}
</li>
))}
</ul>
) : (
<Typography.Text className="ant-form-text" type="secondary">
( <Icon type="smile" /> No user yet. )
</Typography.Text>
);
}}
</Form.Item>
<Form.Item {...tailLayout}>
<Button htmlType="submit" type="primary">
Submit
</Button>
<Button htmlType="button" style={{ marginLeft: 8 }} onClick={showUserModal}>
Add User
</Button>
</Form.Item>
</Form>
<ModalForm visible={visible} onCancel={hideUserModal} />
</Form.Provider>
</div>
);
};
ReactDOM.render(<Demo />, mountNode);
```
```css
#components-form-demo-form-context .user {
margin-bottom: 8px;
}
#components-form-demo-form-context .user .ant-avatar {
margin-right: 8px;
}
```