23

在我的组件的渲染方法中,我将 antd Modal 组件作为父组件,将 antd 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 />
            </Modal>
...

如何通过单击模态保存按钮提交我的表单?

4

8 回答 8

35

有一个看起来更干净的新解决方案:

<Form id="myForm">

...

<Modal
    ...
    footer={[
        <Button form="myForm" key="submit" htmlType="submit">
            Submit
        </Button>
        ]}
>
    <CustomForm />
</Modal>

这是因为 Button 的form属性。浏览器支持

原解决方案作者:https ://github.com/ant-design/ant-design/issues/9380

于 2018-11-21T16:43:29.547 回答
8

可以学习官方例子:https ://ant.design/components/form/#components-form-demo-form-in-modal

于 2016-12-27T01:52:27.787 回答
6

我的解决方案是将模态对话和表单组件包装在一个新的包装父组件中,我在其中验证了 handleCreate 方法中的子表单组件。我使用 ref 属性来引用 FormOnModalWrapper 组件内的 myForm 子组件。我通过 props 将父处理程序从包装父组件传递到 myForm 组件实例。

class FormOnModalWrapper extends React.Component {
...
    constructor(props) {
        this.state =
        {
            visible: false
            ....
        }

...
    showModal = () => {
        this.setState({
            visible: true,
        });
    }

    handleCreate = () => {
        const form = this.form;
        form.validateFields((err, values) => {
            if (err) {
                return;
            }
            console.log('Received values of form: ', values);
            form.resetFields();
            this.setState({ visible: false });
        });
    }

    saveFormRef = (form) => {
        this.form = form;
    }

render() {
...
    const myForm= Form.create()(CrateNewItemFormOnModal);
...
    return (
      <div>
            <Button onClick={this.showModal}>Add</Button>
            <myForm
                visible={this.state.visible}
                onCancel={this.handleCancel}
                onCreate={this.handleCreate}
                ref={this.saveFormRef}
            />
      </div>
     );
}

在 CrateNewItemFormOnModal 组件类中,我将模态对话组件作为父组件,将表单组件作为子组件:

export default class AddNewItemForm extends React.Component {

render() {
    ...
    const { visible, onCancel, onCreate, form } = this.props;
    ...
    return (
        <Modal
           title="Create new item"
           visible={visible}
           onOk={onCreate}
           onCancel={onCancel}
           okText="Create"
        >
          <Form>
            ...
          </Form>
        </Modal>
    );
}
于 2016-12-23T13:36:56.280 回答
6

我的解决方案是使用钩子

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>
    </>
  )
}
于 2021-01-26T08:19:28.737 回答
1

现在,反应钩子出来了,你也可以使用钩子来实现同样的事情。通过为模式创建一个包装器组件并在表单所在的位置使用该组件。

包装器组件:

 <Modal
  visible={state}
  centered={true}
  onCancel={() => setState(false)}
  title={title}
  destroyOnClose={true}
  footer={footer}>
  {children}
</Modal>

表单组件:

   <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>

在这里,我创建了一个包装器模态组件,它具有模态所需的所有 api,而且我正在为我的模态创建一个自定义按钮

于 2019-06-26T07:57:53.910 回答
0

我的解决方案第一个解决方案

...
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>
...

或者您可以使用此解决方案

...
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>
...

这个想法是为包装的表单组件设置 ref。

请参阅下面的参考。

参考

于 2020-03-15T14:35:15.910 回答
0

我的解决方案是禁用模式的页脚并创建我自己的提交按钮:

<Modal footer={null}>
  <Form onSubmit={this.customSubmit}>
    ...
    <FormItem>
      <Button type="primary" htmlType="submit">Submit</Button>
    </FormItem>
  </Form>
</Modal>

无需使用此解决方案包装模态。

于 2018-09-18T19:24:14.087 回答
0

在 2021 年做到这一点的简单方法是为模态自定义页脚

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>
        </>
    )
}
于 2021-11-04T18:01:31.013 回答