Open ignatevdev opened 5 years ago
You can make the Send to moderation button type=button
which will not submit the form, but call your custom function which will run submit and call whatever additional logic is needed.
You can make the Send to moderation button
type=button
which will not submit the form, but call your custom function which will run submit and call whatever additional logic is needed.
Can you provide an example? I'm stuck on this also
You can make the Send to moderation button
type=button
which will not submit the form, but call your custom function which will run submit and call whatever additional logic is needed.Can you provide an example? I'm stuck on this also
I think Something like this should work
const sendToModeration = (values) => {};
const submitForm = (values) => {};
return <Form onSubmit={(values) => {
// default submit code
submitForm(values);
}>
{({ handleSubmit, form: { getState } }) => <form onSubmit={handleSubmit}>
<input type="submit" />
<input type="button" onClick={() => sendToModeration(getState().values}} />
</form>}
</Form>
Having a similar problem, there is no way to run server side validation and bind back errors.
I figured out i can swap onSubmit
but issue i'm having with that is that you can't get original onSubmit to restore it.
From what i understand you can't do that from mutator either
() => {
setConfig('onSubmit', async (values) => {
console.log('submit', values);
});
submit().finally(
() => {
// setConfig('onSubmit', originalSubmit)
}
)
}
I would also love to have this feature to pass a variable to onSubmit() via handleSubmit()
But seems like RFF is a little dead, which is sad because it is really awesome without all the hidden gotchas and slow performance I have seen in other state-form management libraries...
Are you submitting a bug report or a feature request?
Feature request
What is the current behavior?
onSubmit
only receives predefined arguments without an option to pass some custom data throughhandleSubmit()
orform.submit()
What is the expected behavior?
It would be very useful if
handleSubmit
could accept more than one variable, and pass these variables to theonSubmit
call.Use case
Consider having a form with two actions: Save and Send to moderation
In both cases the form should first go through basic validation, then save the data, but if user has chosen to "Send to moderation", we should make an additional validation check and require more fields, and if this validation passes - make one more api call.
It is currently possible to take the values from the form's render props and make a custom callback. However, the only non-hacky way to throw submit errors is to return them from
onSubmit
. Therefore, unless we are able to pass some custom data, in this case - user's action, we would not be able to achieve the desired behaviour without using some hacks like saving the action via theuseRef
before callingonSubmit
.
@ignatevdev This would be useful. I ran into the exact same challenge! I would like to pass an extra argument to onSubmit/handleSubmit
then use it inside the submit handler
to control what to do with the server response
. How did you solve this with useRef
?
Another approach is to use some field as container for your custom option:
const handleSubmit = async ({ action, ...values }, form) => {
if (action === "delete") {
...
} else {
...
}
}
...
<Form onSubmit={handleSubmit}>
{({
form: {
change,
},
submitting,
}) => (
<DeleteButton
type="submit"
onClick={() => change("action", "delete")}
disabled={submitting}
>
Delete
</DeleteButton>
<Button
type="submit"
onClick={() => change("action", "save")}
disabled={submitting}
isLoading={submitting}
label="Save"
/>
)}
</Form>
Yep, its not about refs, but you can pass some flag and make condition inside submit based on its value.
Another approach is to use some field as container for your custom option:
const handleSubmit = async ({ action, ...values }, form) => { if (action === "delete") { ... } else { ... } } ... <Form onSubmit={handleSubmit}> {({ form: { change, }, submitting, }) => ( <DeleteButton type="submit" onClick={() => change("action", "delete")} disabled={submitting} > Delete </DeleteButton> <Button type="submit" onClick={() => change("action", "save")} disabled={submitting} isLoading={submitting} label="Save" /> )} </Form>
Yep, its not about refs, but you can pass some flag and make condition inside submit based on its value.
@batcoh, this looks good but what if I do not want to touch form state
? Like a common no-op
action but should take place after submit
succeeds?
Is that solution even race-safe? Would change block and ensure state before submitting?
@shulcsm I think it safe enough, I use it in production.
onSubmit
fires only after onClick
handler is done and only if click event is not prevented by event.preventDefault
.
FormAPI.change
is synchronous.
However, there is no guarantee, AFAIK events order is not described in the standards and depends on browser implementation. But it works well in my tests and with my use cases.
I made a minimal example in Codesandbox, you can try it on your own.
@chaiwa-berian I personally use final-form-submit-listener to make something in separate handler after submit succeeded. And I still can check for "action" (or any other field) value in this handler via FormAPI.
Not sure if it would be recommended, but the onSubmit
and other parts of the formApi
can be configured dynamically using setConfig
. setConfig
doesn't seem to be listed in the documentation, but it's there in the code. I found this to work to implement different submission strategies:
const onSave = () => { ... }
const onSend = () => { ... }
const { setConfig, submit } = useForm();
const onClickSave = () => {
setConfig('onSubmit', onSave);
submit();
}
const onClickSend = () => {
setConfig('onSubmit', onSend);
submit();
}
return (
<>
<Button onClick={onClickSave}>Save</Button>
<Button onClick={onClickSend}>Send</Button>
</>
);
References:
I think another option is to have the additional data in initialValues. Then make the submit button have a type of button instead of submit and onClick update the value and have the data we want to pass. Finally, make a call to the submit method which will be called with the parameters of the additional data attached to values and can be accessed in onSubmit like:
const onSubmit = (values) => {
console.log(values.additinalData);
}
Are you submitting a bug report or a feature request?
Feature request
What is the current behavior?
onSubmit
only receives predefined arguments without an option to pass some custom data throughhandleSubmit()
orform.submit()
What is the expected behavior?
It would be very useful if
handleSubmit
could accept more than one variable, and pass these variables to theonSubmit
call.Use case
Consider having a form with two actions: Save and Send to moderation
In both cases the form should first go through basic validation, then save the data, but if user has chosen to "Send to moderation", we should make an additional validation check and require more fields, and if this validation passes - make one more api call.
It is currently possible to take the values from the form's render props and make a custom callback. However, the only non-hacky way to throw submit errors is to return them from
onSubmit
. Therefore, unless we are able to pass some custom data, in this case - user's action, we would not be able to achieve the desired behaviour without using some hacks like saving the action via theuseRef
before callingonSubmit
.