Search code examples
reactjsformsmodal-dialogsemantic-uisemantic-ui-react

React - Form submit button in parent Modal


I have a Semantic UI Form:

import {Form} from 'semantic-ui-react';

<MyForm>
    <Form onSubmit={_handleSubmit}>
        <Form.Input name="myInput" label="My Label" value="" />
        <Form.Group>
            <Form.Button>Submit</Form.Button>
        </Form.Group>
    </Form>
</MyForm>

This form can be displayed inside a modal, or directly in a standard view in my app

My modal looks like this:

import {Button, Modal} from 'semantic-ui-react';

<Modal open={true} size="large" centered>
    <Modal.Header>My Label</Modal.Header>
    <Modal.Content>
        <MyForm />
    </Modal.Content>
    <Modal.Actions>
        <Button className="close-button">Cancel</Button>
        {/* Insert submit button here*/}
    </Modal.Actions>
</Modal>

This simple approach is working.

What I would like to do, is to have the submit button inside the Modal.Actions section when it's displayed in a modal, and keep it right after the input otherwise.

I don't know how to tell my form that the submit button is somewhere in its parent.


Solution

  • I finally managed to do it using a ref. The idea is to create a ref in the form, pointing to the submit function and having a function in props to transmit this ref to my modal.

    Modal:

    import {Button, Modal} from 'semantic-ui-react';
    
    const [submitFunc, setSubmitFunc] = useState();
    const submitForm = () => {
        if (submitFunc) {
            submitFunc.current();
        }
    };
    
    <Modal open={true} size="large" centered>
        <Modal.Header>My Label</Modal.Header>
        <Modal.Content>
            <MyForm setSubmitFunc={setSubmitFunc} />
        </Modal.Content>
        <Modal.Actions>
            <Button>Cancel</Button>
            <Button onClick={submitForm}>Submit</Button>
        </Modal.Actions>
    </Modal>
    

    Form:

    function EditRecordForm({setSubmitFunc}) {
        const submitRef = useRef(null);
        useEffect(() => {
            if (!!setSubmitFunc) {
                setSubmitFunc(submitRef);
            }
        });
    
        const handleSubmit = () => {
            // Do whatever you need to retrieve form values and submit it
        }
        submitRef.current = handleSubmit;
    
        return (
            <MyForm>
                <Form onSubmit={_handleSubmit}>
                    <Form.Input name="myInput" label="My Label" value="" />
                    <Form.Group>
                        <Form.Button>Submit</Form.Button>
                    </Form.Group>
                </Form>
            </MyForm>
        )
    }