如何使用antd react组件库在模态对话中提交表单组件

时间:2016-12-19 11:31:02

标签: reactjs antd

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

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

7 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

答案 2 :(得分:2)

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

<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

答案 3 :(得分:2)

我的解决方案是使用钩子

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

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

现在,反应钩子已经出来了,您也可以使用钩子来实现相同的目的。通过为模式创建包装器组件并在表单所在的位置使用该组件。

包装器组件

 <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 :(得分: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>
...

这个想法是为包装表单组件设置引用。

请参阅下面的参考。

Reference