【问题标题】:How to submit form component in modal dialogue using antd react component library如何使用antd react组件库在模态对话中提交表单组件
【发布时间】:2017-05-04 10:45:36
【问题描述】:

在我的组件的渲染方法中,我将 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>
...

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

【问题讨论】:

    标签: reactjs antd


    【解决方案1】:

    我的解决方案是将模态对话和表单组件包装在一个新的包装父组件中,在该父组件中我在 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>
        );
    }
    

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 始终欢迎提供指向潜在解决方案的链接,但请add context around the link,以便您的其他用户知道它是什么以及为什么存在。始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。考虑到仅仅是指向外部站点的链接Why and how are some answers deleted? 的一个可能原因。
      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        <Form id="myForm">
        

        ...

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

        这是因为 Button 的 form 属性。 Browser support

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

        【讨论】:

          【解决方案5】:

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

          包装组件:

           <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,并且我正在为我的模态创建一个自定义按钮

          【讨论】:

            【解决方案6】:

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

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

            请参阅下面的参考资料。

            Reference

            【讨论】:

              【解决方案7】:

              我的解决方案是使用钩子

              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>
                  </>
                )
              }
              

              【讨论】:

                【解决方案8】:

                在 2021 年做到这一点的简单方法是制作 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>
                        </>
                    )
                }
                

                【讨论】:

                  猜你喜欢
                  • 2021-07-06
                  • 1970-01-01
                  • 2016-11-14
                  • 2017-10-19
                  • 2022-12-22
                  • 2021-03-08
                  • 2020-12-30
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多