mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-05 01:19:45 +08:00
3d8cd0b451
* feat: switch visible to open for Modal * test: depcated check * docs: site api update Co-authored-by: 二货机器人 <smith3816@gmail.com>
165 lines
4.3 KiB
Markdown
165 lines
4.3 KiB
Markdown
---
|
||
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 { SmileOutlined, UserOutlined } from '@ant-design/icons';
|
||
import { Avatar, Button, Form, Input, InputNumber, Modal, Typography } from 'antd';
|
||
import type { FormInstance } from 'antd/es/form';
|
||
import React, { useEffect, useRef, useState } from 'react';
|
||
|
||
const layout = {
|
||
labelCol: { span: 8 },
|
||
wrapperCol: { span: 16 },
|
||
};
|
||
const tailLayout = {
|
||
wrapperCol: { offset: 8, span: 16 },
|
||
};
|
||
|
||
interface UserType {
|
||
name: string;
|
||
age: string;
|
||
}
|
||
|
||
interface ModalFormProps {
|
||
open: boolean;
|
||
onCancel: () => void;
|
||
}
|
||
|
||
// reset form fields when modal is form, closed
|
||
const useResetFormOnCloseModal = ({ form, open }: { form: FormInstance; open: boolean }) => {
|
||
const prevOpenRef = useRef<boolean>();
|
||
useEffect(() => {
|
||
prevOpenRef.current = open;
|
||
}, [open]);
|
||
const prevOpen = prevOpenRef.current;
|
||
|
||
useEffect(() => {
|
||
if (!open && prevOpen) {
|
||
form.resetFields();
|
||
}
|
||
}, [form, prevOpen, open]);
|
||
};
|
||
|
||
const ModalForm: React.FC<ModalFormProps> = ({ open, onCancel }) => {
|
||
const [form] = Form.useForm();
|
||
|
||
useResetFormOnCloseModal({
|
||
form,
|
||
open,
|
||
});
|
||
|
||
const onOk = () => {
|
||
form.submit();
|
||
};
|
||
|
||
return (
|
||
<Modal title="Basic Drawer" open={open} 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 App: React.FC = () => {
|
||
const [open, setOpen] = useState(false);
|
||
|
||
const showUserModal = () => {
|
||
setOpen(true);
|
||
};
|
||
|
||
const hideUserModal = () => {
|
||
setOpen(false);
|
||
};
|
||
|
||
const onFinish = (values: any) => {
|
||
console.log('Finish:', values);
|
||
};
|
||
|
||
return (
|
||
<Form.Provider
|
||
onFormFinish={(name, { values, forms }) => {
|
||
if (name === 'userForm') {
|
||
const { basicForm } = forms;
|
||
const users = basicForm.getFieldValue('users') || [];
|
||
basicForm.setFieldsValue({ users: [...users, values] });
|
||
setOpen(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: UserType[] = getFieldValue('users') || [];
|
||
return users.length ? (
|
||
<ul>
|
||
{users.map((user, index) => (
|
||
<li key={index} className="user">
|
||
<Avatar icon={<UserOutlined />} />
|
||
{user.name} - {user.age}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
) : (
|
||
<Typography.Text className="ant-form-text" type="secondary">
|
||
( <SmileOutlined /> No user yet. )
|
||
</Typography.Text>
|
||
);
|
||
}}
|
||
</Form.Item>
|
||
<Form.Item {...tailLayout}>
|
||
<Button htmlType="submit" type="primary">
|
||
Submit
|
||
</Button>
|
||
<Button htmlType="button" style={{ margin: '0 8px' }} onClick={showUserModal}>
|
||
Add User
|
||
</Button>
|
||
</Form.Item>
|
||
</Form>
|
||
|
||
<ModalForm open={open} onCancel={hideUserModal} />
|
||
</Form.Provider>
|
||
);
|
||
};
|
||
|
||
export default App;
|
||
```
|
||
|
||
```css
|
||
#components-form-demo-form-context .user {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
#components-form-demo-form-context .user .ant-avatar {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.ant-row-rtl #components-form-demo-form-context .user .ant-avatar {
|
||
margin-right: 0;
|
||
margin-left: 8px;
|
||
}
|
||
```
|