React: Remote form submission via dispatchEvent broken in Firefox

Created on 18 Apr 2018  ·  12Comments  ·  Source: facebook/react

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

The following does not result in onSubmit being called (_only in Firefox_):

document
  .getElementById("exampleForm")
  .dispatchEvent(new Event("submit"))}

Edit 🏁  React Final Form - External Submit Button

☝️ Click the "External Submit via document.getElementById() button.

One of the things I love about React is how it smooths out the browser idiosyncrasies that plagued web development for so many years. It's rare to find an edge case like this. However, this is a pretty weird way to submit a form...

Originally from https://github.com/final-form/react-final-form/issues/181.

What is the expected behavior?

Seems like onSubmit should be called. Maybe this is a bug with Firefox and not React? 🤷‍♂️

Or maybe there's a better way to do this compatible across all browsers?

Which versions of React, and which browser / OS are affected by this issue?

React 16.3.2
Firefox 59.0.2
Mac 10.13.4

Did this work in previous versions of React?

No idea. 🤷‍♂️

DOM Needs More Information

Most helpful comment

Thanks for clarifying! The "No React" example you provided doesn't looks to represent the same scenario. We want to test if running dispatchEvent works with preventDefault for submit events.

Here's a fork that uses dispatchEvent, you can see it also doesn't prevent default on the event.

The reason for this is that you need to set cancelable to true when creating an event and dispatching it manually, if you want to call preventDefault on it.

form.dispatchEvent(new Event('submit', { cancelable: true }))

Here's a working example with React. I'm surprised that Chrome and other browsers allow preventDefault with a non-cancellable event. In any case, it doesn't look to be a React issue.

Hope that helps!

All 12 comments

Can you please reduce this to a ReactDOM-only example with no third-party libs and extra code, and also verify you don't have this problem without React?

No 3rd party libs - Fails in Firefox:

Edit React Firefox Bug? #12639

No React - Works in Firefox:

Edit rl28y4nx9o

Man, coding in non-React sucks! 🤣

@erikras I'm confused, can you clarify what the specific issue you're reporting is? In your first example the onSubmit handler _is_ called, but you're using an async function and sleep'ing for 3 seconds. If you remove the sleep call, the alert shows as expected. I'm not sure what the spec'd behavior is for async functions and native events.

In your example without 3rd party libs, you're no longer using an async function and it appears to be working in Firefox for me. The issue I see is that the preventDefault call isn't actually preventing default for some reason, so that's a separate issue.

In your example without React it's also not using an async function. Here's a fork of that example using an async function and sleep. You'll see that it doesn't work either.

Are you reporting that async event handlers don't work, preventDefault doesn't work with dispatchEvent, or something else?

This is not about any async/await stuff. Ignore that.

The issue I see is that the preventDefault call isn't actually preventing default for some reason, so that's a separate issue.

That's the main issue.

Are you reporting that async event handlers don't work, preventDefault doesn't work with dispatchEvent?

Yes, that "preventDefault doesn't work with dispatchEvent".

Whether or not dispatchEvent is a sacred DOM API that demands cross-browser respect is up to you guys, but it seems to work on the others (I haven't tested IE, because gross!), and fails to provide the requisite event.preventDefault() functionality in Firefox for some reason. Up to you guys how important this is. I don't care strongly, but I'm just throwing it out there as an inconsistency that might have previously gone unnoticed.

Thanks for clarifying! The "No React" example you provided doesn't looks to represent the same scenario. We want to test if running dispatchEvent works with preventDefault for submit events.

Here's a fork that uses dispatchEvent, you can see it also doesn't prevent default on the event.

The reason for this is that you need to set cancelable to true when creating an event and dispatching it manually, if you want to call preventDefault on it.

form.dispatchEvent(new Event('submit', { cancelable: true }))

Here's a working example with React. I'm surprised that Chrome and other browsers allow preventDefault with a non-cancellable event. In any case, it doesn't look to be a React issue.

Hope that helps!

Thanks, Brandon. That clears it up 100%. The turnaround on this was spectacular. I wish there was a way for me to let your boss know how awesomely you handled this.

@flarnie? I know not of the FB org chart, but heard she was a manager. 🤷‍♂️

@sophiebits manages the React team. But @aweary doesn’t actually work full time on React 🙃

Get back to work on Seattle business, @aweary! 😆

@sophiebits, these dudes are awesome. But, you knew that already...

Noted anyway. Will make sure @aweary's work gets noticed in our next reviews. :)

Grrr, @sophiebits, I was literally just now writing a tweet to you about this. Will tweet anyway.

Hey @aweary thanks for that little tip. I'm not working with React (just coding in non-React 🤣) but MDN and a few SO answers didn't solve this issue, your comment did. FYI Chrome allows this to be prevented, and Firefox, per usual, actually does what's defined in the spec!

Was this page helpful?
0 / 5 - 0 ratings