Reputation: 381
im using react-hook-form for form validation and submission ,everything work's fine with single submit type button, now i need to have three buttons , "Save Draft" ,"Preview Data Values in Page" ,and "Submit for approval " ,i can opt-out for a Mode Selection radio Buttons ,But wanted to have three button submit function, which needs form data . adding onchnage for input fields will work ,but form validation needs to write again .
const { register, handleSubmit } = useForm();
const onSubmit = (data) => alert(JSON.stringify(data));
function NeedTohaveFormDataHere1(Data) {
} function NeedTohaveFormDataHere2(Data) {
}
return ( <form onSubmit={handleSubmit(onSubmit)}>
<Headers />
<input name="firstName" ref={register} placeholder="First name" />
<input name="lastName" ref={register} placeholder="Last name" />
<select name="category" ref={register}>
<option value="">Select...</option>
<option value="A">Category A</option>
<option value="B">Category B</option>
</select>
<button onClick={NeedTohaveFormDataHere1}>
Save Draft
</button >
<button onClick={NeedTohaveFormDataHere2}>
Preview
</button>
<input type="submit" />
</form>
);
}
onSubmit function will get form data ,how to get form data in other two button functions ?
sloved .. with
<button onClick={handleSubmit(NeedTohaveFormDataHere1)}>
Save Draft
</button >
<button onClick={handleSubmit(NeedTohaveFormDataHere2)}>
Preview
</button>
Upvotes: 27
Views: 48385
Reputation: 331
I had the same problem and I resolved it the following way:
I have two buttons. The first button validates and submits the form normally. The second button only validates and calls a custom function.
I'm assuming you have the situation. One button is to save and the other one is to store a draft.
<form id="example-form" onSubmit={handleSubmit(handleOnSave)}>
<IconButtonTooltip
form="example-form"
title="Only save"
>
<SaveIcon className={classes.icon} />
</IconButtonTooltip>
<IconButtonTooltip
form="example-form"
title="Save and sign"
onClick={handleSubmit(handleOnSingAndSave)}
>
<SignatureIcon className={classes.icon} />
</IconButtonTooltip>
</form>
const handleOnSingAndSave = () => {
// Handle things...
}
It works for me!
Upvotes: 23
Reputation: 9042
Add a name attribute to your button. Then:
JavaScript
async function onSubmit(values, e) {
const submitter = e?.nativeEvent?.submitter;
console.log(submitter?.name);
TypeScript
async function onSubmit(
values: z.infer<typeof formSchema>,
e: React.FormEvent<HTMLFormElement>,
) {
if (!(e.nativeEvent instanceof SubmitEvent)) return;
const submitter = e?.nativeEvent?.submitter as HTMLButtonElement;
if (!(submitter instanceof HTMLInputElement)) return;
console.log(submitter?.name);
CanIuse SubmitEvent is safe: https://caniuse.com/?search=SubmitEvent
Upvotes: 8
Reputation: 101
You Can add name or id to your button and check the button type as in modern browsers button type is submit by default
<button name="submit">Submit</button>
<button name="draft">Draft</button>
<form onSubmit={handleSubmit} > ...
function handleSubmit(event) {
event.preventDefault(); // Prevent form submission
const buttonType = event.submitter.getAttribute("name");
switch (buttonType) {
case "submit":
// Handle submit button click
alert("Submit button clicked");
break;
case "draft":
// Handle draft button click
alert("Save Draft button clicked");
break;
default:
// Handle other cases if needed
break;
}
}
Upvotes: 1
Reputation: 1
I stumbled across the same problem, I solved it by adding an onClick event to each submit button with a setValue() function. Example:
import { useForm } from 'react-hook-form';
const { register, handleSubmit, setValue } = useForm();
const onSubmit = (data) => {
console.log(data.method)
}
<form onSubmit={handleSubmit(onSubmit)}>
<button type='submit' name='A' {...register('method')} onClick={() => setValue('method', 'A')}>A button</button>
<button type='submit' name='B' {...register('method')} onClick={() => setValue('method', 'B')}>B button</button>
</form>
Upvotes: 0
Reputation: 31
I used yup with resolver for validation so my answer might differ. I also used trigger to validate without submitting. I also reset the form so that it won't be marked 'dirty' after saving.
export default function MyForm(props) {
const {
control,
reset,
trigger,
handleSubmit,
getValues,
formState: { isDirty },
} = useForm({
mode: "onBlur",
reValidateMode: "onBlur",
shouldUnregister: true,
defaultValues: {
name: "",
id: "",
//rest of values
},
resolver: yupResolver(schema),
});
const handleOnSubmit = async (event) => {
if(!isDirty){
//navigate out of page
} else {
//save and exit
}
}
const handleOnSave = async () => {
trigger(); //triggers validation for whole form
const formValue = getValues();
const isValid = schema.isValidSync(formValue);
if(isValid){
//await save actions
if(savedSuccessfully){
reset(formValue);
//anything else
}
}
};
}
Upvotes: 1
Reputation: 7169
I did it in the next way:
onSubmit
- form submission handler
<Button type="submit">Post</Button>
<Button
appearance="stroke"
onClick={handleSubmit((data) =>
onSubmit({
...data,
status: CreateResumeRequestStatusEnum.Draft,
})
)}
>
Save for later
</Button>
Upvotes: -1
Reputation: 608
You can try giving name and type to a button and catch it using window.event.submitter.name.
<button type="submit" name="submit">Submit</button>
<button type="submit" name="draft">Draft</button>
<form onSubmit={handleSubmit} > ...
const handleSubmit = () => {
const buttonType=window.event.submitter.name // will return draft or submit and you can handle it using switch case.
if(buttonType==="submit"){
//HANDLE SUBMIT FUNCTION
return;
}
if(buttonType==="draft"){
//HANDLE DRAFT FUNC
return;
}
}
But this solution doesn't work in safari
Upvotes: 1
Reputation: 2481
if you have to handle the multiple submit buttons in react-hook-form
1. remove your submit method from the form tag and add it to your button click
2. move your submit buttons outside the form tag
const { handleSubmit } = useForm();
<form>
<input />
<input />
</form>
<button onClick={handleSubmit((d) => console.log(d))} > Save </button>
<button onClick={handleSubmit((d) => console.log(d))} > Draft </button>
Upvotes: 17
Reputation: 195
You can use handleSubmit in multiple place.
const handleSubmitDraft=()=>{
handleSubmit(aync(data)=>{...})()
}
const handleSubmitPreview=()=>{
handleSubmit((data)=>{...})()
}
<button onClick={handleSubmitDraft}>
Save Draft
</button >
<button onClick={handleSubmitPreview}>
Preview
</button>
Upvotes: 13