Short answer as of 2022-09-08
As Vasiliy answered, for modern browsers we should just use requestSubmit
. For old browsers, we should not use dispatchEvent
since it will never trigger native form submission action. We should rely on programatic click of button elements instead as a polyfil. Keep reading if you are interested in more details, which is also applicable for non-React situations.
Long answer
Although the usage of dispatchEvent
is recommended in several places on the Internet to do programatic form submission, I think we should not use it because it will rely on "implementation details" of the event handling strategy on the page, which is typically different per framework.
Even framework (e.g. React) version change can break the behavior.
The world without JS frameworks (e.g. React)
First of all, dispatchEvent
does not work at all for form submission when not using framework like React.
There is a relevant issue in The Chromium issue tracker:
Dispatching non-trusted 'submit' event should not start form submission.
Just note that events dispatched by dispatchEvent
are "non-trusted" (see MDN)
HTMLFormElement.submit()
has been "the way" for a while to programatically submit the form (MDN) when there is framework usage or the framework is relying on native form submission behavior.
The world with frameworks (e.g. React)
Frameworks like React do event handling by its own (typically via event delegation, which means submit
event need to be fired to make sure React onSubmit
handler just works as expected.
Because of this, we cannot simply rely on HTMLFormElement.submit()
, which does not raise submit
event as explained in MDN.
Thinking of the best way to closely emulate what real users would do, we can use HTMLElement.click()
.
const myForm = document.querySelector('form');
const btn = document.createElement('button');
myForm.appendChild(btn);
myForm.onsubmit = ev => {
// Interestingly, this event is "trusted" although the click was done programatically
console.log(ev.isTrusted)
}
btn.click();
myForm.removeChild(btn);
Creating temporary <button>
and use HTMLElement.click()
should be reliable across all the JavaScript code / framework because this properly raise submit
event (this is also trusted event so framework cannot distinguish this with manual form submission via real submit button). For example, when using React, onSubmit
handler should be properly called.
However, after this exploration, I just found there is relatively new method in HTMLFormElement. It is HTMLFormElement.requestSubmit(), which does fire submit
event so frameworks like React can react to this programatic trigger. If you can target Safari 16, you should just use requestSubmit()
. For older browsers, I found a polyfill, which actually does almost the same thing as the above snippet; creating adhoc button element and call .click
.