'How to submit form component in modal dialogue using antd react component library
In my component's render method I have antd Modal component as a parent and antd Form component as a child:
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm />
</Modal>
...
How can I submit my form by clicking the Modals Save button?
Solution 1:[1]
There is a new solution that looks much cleaner:
<Form id="myForm">
...
<Modal
...
footer={[
<Button form="myForm" key="submit" htmlType="submit">
Submit
</Button>
]}
>
<CustomForm />
</Modal>
This works because of the Button's form attribute. Browser support
Original solution's author: https://github.com/ant-design/ant-design/issues/9380
Solution 2:[2]
My solution is using hooks
import { Button, Modal, Form } from 'antd';
export default function ModalWithFormExample() {
const [visible, setVisible] = useState(false);
const [form] = Form.useForm();
const showModal = () => {
setVisible(true)
}
const handleSubmit = (values) => {
console.log(values)
}
const handleCancel = () => {
setVisible(false)
form.resetFields()
};
return (
<>
<Button onClick={showModal}>Open Modal</Button>
<Modal visible={visible} onOk={form.submit} onCancel={handleCancel}>
<Form form={form} onFinish={handleSubmit}>
{/* Any input */}
</Form>
</Modal>
</>
)
}
Solution 3:[3]
You can study official example: https://ant.design/components/form/#components-form-demo-form-in-modal
Solution 4:[4]
My solution was to disable the modal's footer and create my own submit button:
<Modal footer={null}>
<Form onSubmit={this.customSubmit}>
...
<FormItem>
<Button type="primary" htmlType="submit">Submit</Button>
</FormItem>
</Form>
</Modal>
No need to wrap the modal with this solution.
Solution 5:[5]
Now, react hooks are out you can achieve the same thing using hooks also. By creating a wrapper component for the modal and used that component where the form is.
Wrapper Component:
<Modal
visible={state}
centered={true}
onCancel={() => setState(false)}
title={title}
destroyOnClose={true}
footer={footer}>
{children}
</Modal>
Form Component:
<WrapperModal
state={modalState}
setState={setModal}
title='Example Form'
footer={[
<button onClick={handleSubmit}>
SUBMIT
<button/>
]}>
<Form>
<Form.Item label='name '>
{getFieldDecorator('name ', {
rules: [
{
required: true,
message: 'please enter proper name'
}
]
})(<Input placeholder='name'/>)}
</Form.Item>
</Form>
</WrapperModal>
here i had created a wrapper modal component which have all the necessary api for the modal, also i am creating a custom buttons for my modal
Solution 6:[6]
My solution 1st solution
...
handleOk = (e) => {
e.preventDefault();
this.form.validateFields((err, values) => {
//do your submit process here
});
}
//set ref form
formRef = (form) => {
this.form = form;
}
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm
ref={this.formRef}
/>
</Modal>
...
or you can use this solution
...
handleOk = (e) => {
e.preventDefault();
this.form.validateFields((err, values) => {
//do your submit process here
});
}
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm
wrappedComponentRef={(form) => this.formRef = form}
/>
</Modal>
...
The idea is to set the ref for wrapped the form component.
Please see the reference below.
Solution 7:[7]
Simple way to do this in 2021 is making customized footer for modal
import { useState } from 'react'
import { Modal, Button, Form, Input } from 'antd'
export default function BasicModal() {
const [form] = Form.useForm()
const [isModalVisible, setIsModalVisible] = useState(false)
const showModal = () => setIsModalVisible(true)
const handleCancel = () => {
setIsModalVisible(false)
form.resetFields()
}
const handleOk = () => {
form.submit()
}
const onFinish = () => {
console.log('Form submited!')
setIsModalVisible(false)
}
return (
<>
<Button type="primary" onClick={showModal}>
Show Modal
</Button>
<Modal
title="Basic Modal"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
footer={[
<Button key="back" onClick={handleCancel}>
Cancel
</Button>,
<Button key="submit" type="primary" onClick={handleOk}>
Submit
</Button>,
]}
>
<Form labelCol={{ xs: { span: 6 } }} wrapperCol={{ xs: { span: 12 } }} form={form} onFinish={onFinish} scrollToFirstError>
<Form.Item name="input1" label="Input 1" rules={[{ required: true, message: "This field is required." }]}>
<Input />
</Form.Item>
<Form.Item name="input2" label="Input 2" rules={[{ required: true, message: "This field is required." }]}>
<Input />
</Form.Item>
</Form>
</Modal>
</>
)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | sensor |
| Solution 2 | Chhaileng |
| Solution 3 | benjycui |
| Solution 4 | JacopoStanchi |
| Solution 5 | Wasif |
| Solution 6 | Ashadi Sedana Pratama |
| Solution 7 | Closery |
