dohomi/react-hook-form-mui

How to trigger form submit from an inner component programmatically?

Closed this issue ยท 3 comments

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Summary ๐Ÿ’ก

I'm using FormContainer with onSuccess to get the data to save on the server.
I have a custom component which listen for "cmd+s, ctrl+s" to catch save shortcut and submit the form.
What would be the recommendation in this case?

There is no hook from the react-hook-form-mui to get the parent form and trigger a DOM Event submit right?

Examples ๐ŸŒˆ

    <FormContainer
        formContext={formContext}
        onSuccess={async (data) => {
             //save to server
        }}>
                <TextFieldElement
                    margin="dense"
                    required={!!member}
                    fullWidth
                    label="ID"
                    name="id"
                    variant="filled"
                    disabled={true}
                    size="small"
                />

            <LoadingButton
                type="submit"
                disabled={formState.isSubmitting}
                loading={formState.isSubmitting}
                fullWidth
                variant="contained"
                sx={{ mt: 2, mb: 2 }}>
                {member ? 'Save' : 'Add member'}
            </LoadingButton>

        <SaveShortcut/>
</FormContainer

SaveShortcut.tsx


export const SaveShortcut = ( ) => {
    const { handleSubmit, ...other } = useFormContext()
    useHotkeys(['ctrl+s', 'meta+s'], (event) => {
        console.log('save shortcut')
        event.preventDefault()
        //handleSubmit()()
        // other.trigger()
        // formRef.current.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }))
    })

    return null
}

Something like this does the work but it there a better solution?

export const SaveShortcut = () => {
    const ref = useRef(null)
    useHotkeys(['ctrl+s', 'meta+s'], (event) => {
        event.preventDefault()
        // @ts-ignore
        const form = ref.current?.closest('form')
        if (form) {
            form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }))
        }
    })

    return <div ref={ref}></div>
}
dohomi commented

@HugoGresse there are many ways to do it, yours is quite alright. But you can also create the useForm context first, pass the context to FormContainer and also forward the onSubmit similar to the example of Storybook https://github.com/dohomi/react-hook-form-mui/blob/master/apps/storybook/stories/FormContainer.stories.tsx#L79

this way you don't have to create a subcomponent and use the useHotkeys hook directly on toplevel element.

Thanks for the quick answer, I liked the idea of not interfacing with my own state management, thus keeping the form submit action to only be in the onSuccess of the form container. I'm closing this as it now has 2 answers and should be enough for most peoples!