diff --git a/src/Form/index.tsx b/src/Form/index.tsx index 1dcfb6d..a18a33d 100644 --- a/src/Form/index.tsx +++ b/src/Form/index.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect } from 'react' import axios from 'axios' -import { type Visit } from '@inertiajs/core' +import { type VisitOptions } from '@inertiajs/core' import useInertiaForm, { NestedObject } from '../useInertiaForm' import { useForm, type UseFormProps, type HTTPVerb, FormProvider } from './FormProvider' import FormMetaWrapper, { useFormMeta, type FormMetaValue } from './FormMetaWrapper' @@ -13,6 +13,7 @@ export interface FormProps extends PartialHTMLForm { method?: HTTPVerb to?: string async?: boolean + resetAfterSubmit?: boolean remember?: boolean railsAttributes?: boolean onSubmit?: (form: UseFormProps) => boolean|void @@ -28,6 +29,7 @@ const Form = ({ method = 'post', to, async = false, + resetAfterSubmit, remember = true, onSubmit, onChange, @@ -35,18 +37,17 @@ const Form = ({ onError, ...props }: Omit, 'railsAttributes'>) => { - const form = remember && (model || to) ? useInertiaForm(`${method}/${model || to}`, data) : useInertiaForm(data) const contextValueObject = useCallback((): UseFormProps => ( { ...form, model, method, to, submit } - ), [form.data, form.errors]) + ), [data, form.data, form.errors]) /** * Submits the form. If async prop is true, submits using axios, * otherwise submits using Inertia's `useForm.submit` method */ - const submit = async (options?: Partial) => { + const submit = async (options?: Partial) => { let shouldSubmit = to && onSubmit && onSubmit(contextValueObject()) === false ? false : true if(shouldSubmit) { @@ -62,7 +63,14 @@ const Form = ({ e.preventDefault() e.stopPropagation() - submit() + submit({ + onSuccess: () => { + if(resetAfterSubmit || (resetAfterSubmit !== false && async === true)) { + form.reset() + } + if(onSuccess) onSuccess(contextValueObject()) + }, + }) } // Set values from url search params. Allows for prefilling form data from a link @@ -82,13 +90,6 @@ const Form = ({ if(onError) onError(contextValueObject()) }, [form.errors]) - useEffect(() => { - if(!form.wasSuccessful) return - - form.reset() - if(onSuccess) onSuccess(contextValueObject()) - }, [form.wasSuccessful]) - return (
diff --git a/src/Inputs/Submit.tsx b/src/Inputs/Submit.tsx index ebac77a..9318877 100644 --- a/src/Inputs/Submit.tsx +++ b/src/Inputs/Submit.tsx @@ -9,9 +9,9 @@ const Submit = React.forwardRef(( { children, type = 'submit', disabled, component = 'button', ...props }, ref, ) => { - const { processing } = useForm() + const { processing, isDirty } = useForm() - const finalProps = { children, type, disabled: disabled || processing, ref, ...props } + const finalProps = { children, type, disabled: disabled || processing || !isDirty, ref, ...props } if(typeof component === 'string') { return React.createElement(component, finalProps) diff --git a/src/useInertiaForm.ts b/src/useInertiaForm.ts index 8dfc022..aa3e003 100644 --- a/src/useInertiaForm.ts +++ b/src/useInertiaForm.ts @@ -57,15 +57,20 @@ export default function useInertiaForm( const isMounted = useRef() // Data - let rememberKey = null - let transformedData = rememberKeyOrInitialValues - if(typeof rememberKeyOrInitialValues === 'string') { - rememberKey = rememberKeyOrInitialValues - transformedData = maybeInitialValues - } + const getFormArguments = useCallback((): [string, TForm] => { + let rememberKey: string = null + let transformedData = rememberKeyOrInitialValues + if(typeof rememberKeyOrInitialValues === 'string') { + rememberKey = rememberKeyOrInitialValues + transformedData = maybeInitialValues + } + return [rememberKey, fillEmptyValues(transformedData as TForm)] + }, [rememberKeyOrInitialValues, maybeInitialValues]) + + const [rememberKey, transformedData] = getFormArguments() - const [defaults, setDefaults] = useState((fillEmptyValues(transformedData) || {}) as TForm) - const [data, setData] = rememberKey ? useRemember(defaults, `${rememberKey}:data`) : useState(defaults) + const [defaults, setDefaults] = useState(transformedData || {} as TForm) + const [data, setData] = rememberKey ? useRemember(transformedData, `${rememberKey}:data`) : useState(transformedData) // Errors const [errors, setErrors] = rememberKey diff --git a/tsconfig.json b/tsconfig.json index b624224..bf1f7ad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ESNext", "module": "esnext", - "lib": ["dom", "esnext"], + "lib": ["dom", "esnext", "dom.iterable"], "jsx": "react", "declaration": true, "sourceMap": true,