Do you want to request a _feature_ or report a _bug_?
Bug
What is the current behavior?
If I have a ref to the form
DOM element and call submit()
on it, it does not trigger the onSubmit
callback.
Repro: https://jsfiddle.net/owiber/r8moy7ey/1/
In the above fiddle, if you hit <enter>
in the input, it properly calls the onSubmit
(alerts). If you click the button, which calls this._form.submit()
, it does not.
What is the expected behavior?
form.submit()
should trigger onSubmit
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
15, Chrome (did not test others, unknown if broken in previous versions)
This is expected behaviour.
See MDN:
The form's onsubmit event handler (for example, onsubmit="return false;") will not be triggered when invoking this method from Gecko-based applications.
Using the onsubmit
event handler and calling submit
(think of it as an API method) is something different.
Aha, gotcha. The button was just for the example, but will go with an alternate approach then.
If anyone else stumbles across this issue:
You can submit from the form element, but you need to dispatch the submit event.
Example:
form.dispatchEvent(new Event('submit'))
Hi from the future,
Im struggling to run this on React 15.6.2
But it does not work
thx in advance
import React from 'react';
export default class extends React.Component {
componentWillReceiveProps(nextProps) {
if(nextProps.forceSubmit) {
this.formRef.dispatchEvent(new Event('submit'));
}
}
handleSubmit(evt) {
evt.preventDefault();
this.props.onSubmit();
}
render() {
return (
<form ref={e => this.formRef = e} onSubmit={evt => this.handleSubmit(evt)}>
{this.props.children}
</form>
)
}
}
Im able to make this work on 16.5.2 btw
Even now with 16.8.6 still not working, I need dispatch event:
const App: React.FC = () => {
const formRef = useRef<HTMLFormElement>(null);
function handleSubmit(e: any) {
e.preventDefault();
console.log("submitting");
}
return (
<div className="App">
<form ref={formRef} onSubmit={handleSubmit}>
content
<button type="submit">Submit Inside</button>
</form>
<button
onClick={() => formRef.current!.dispatchEvent(new Event("submit"))}
>
Submit Outside
</button>
</div>
);
};
@naivefun just to notice you can achieve this with the form attribute of an button:
function App() {
const formId = "something";
return (
<div className="App">
<form id={formId} onSubmit={() => alert("submitted")} />
<button type="submit" form={formId}>
Submit from outside form
</button>
</div>
);
}
running example: https://codesandbox.io/s/3q50nqxxx1
And for those who want to be able to call event.preventDefault()
within the onSubmit handler, then you'll need to modify the event to:
refForm.current.dispatchEvent(new Event('submit', { cancelable: true }))
@raRaRa I would also like to add that:
refForm.current.dispatchEvent(new Event('submit', { cancelable: true }))
does not do the trick when targeting chrome.
However, something like this should help
const form = refForm.current;
if (form) {
if (typeof form.requestSubmit === 'function') {
form.requestSubmit();
} else {
form.dispatchEvent(new Event('submit', {cancelable: true}));
}
}
@benkovy @raRaRa Thank you for your suggestions. However, neither solution seems to work in Firefox. Any suggestions?
I'd also like to point out that the dispatch event workaround means no input "validation" on the form fields, meaning elements with the required tag
<input type="file" required />
are not checked.
Update:
It is possible to use the requestSubmit() method on the form element to trigger field validation + submission. More info here: https://stackoverflow.com/questions/61831661/reactjs-submit-form-onchange?noredirect=1#comment109366001_61831661
Seems like this broke with React 17 for some reason, on Firefox.
Using the requestSubmit
solution seems to work.
Most helpful comment
If anyone else stumbles across this issue:
You can submit from the form element, but you need to dispatch the submit event.
Example: