react: submit() on form element doesn't trigger onSubmit

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)

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 15
  • Comments: 15

Most upvoted comments

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'))

@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

@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}));
  }
}

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 }))

Seems like this broke with React 17 for some reason, on Firefox.

Using the requestSubmit solution seems to work.

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

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.

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>
  );
};

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>
    )
  }
}