11

I'll preface by saying that I'm very familiar with click events and know I can register a click event on a form submit button as many other answers explain. My question is a level deeper.

Forms can be submitted in other ways than clicking submit: I'm thinking like when a user presses enter while focused on an input/select or even by pressing space or enter while focused on the submit button itself…and I'd like to be able to get a reference to the element that submitted the form.

This answer seemed to have promise, but I'm not exactly sure how to 'see' the values he mentions. I made a codepen to demonstrate. *edit: I updated the codepen to reflect the accepted answer below.

It would also seem that the answer is actually inaccurate in that when a user submits a form, the browser triggers the click event on the first submit in the form, not the first submit after the element that triggered the submit (at least when I ran that Codepen in Chrome/Firefox/Safari).

To give some context for why this is necessary, I'm working on an Asp.NET site where every page's content is encapsulated in a monolithic form. I'm adding an email subscription form to the footer that submits asynchronously…which means I need to do an e.preventDefault() on the event and also want to avoid accidental submissions if the form is actually being submitted from somewhere else like the search bar up top or a form I wasn't aware of.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
joshdcomp
  • 1,618
  • 3
  • 19
  • 26

3 Answers3

16

You can use document.activeElement This will work for clicks and when the user tabs to a button and hits the enter button.

Listen for the submit event on the form, then inside of the callback, reference document.activeElement, it will be the button that the user clicked or tabbed to.

Example: http://codepen.io/anon/pen/KVoJrJ

unpollo
  • 806
  • 5
  • 15
  • 2
    Look at that! Updated my codepen to use `document.activeElement`, works exactly as I was hoping. Thanks – joshdcomp Jan 27 '16 at 01:59
  • 3
    FWIW this does not work on Firefox or Safari on Mac. From MDN "On Mac, elements that aren't text input elements tend not to get focus assigned to them." This does seem to work on Chrome for Mac though. – Vadim Apr 24 '17 at 15:03
  • Note: buttons aren't focusable on Mac/Safari and `document.activeElement` results in when the submit button is clicked – dehart Oct 21 '20 at 14:17
4

The submit event of a <form> element actually contains a reference to the submitter:
https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter

form.onsubmit = (event) => {
    const formElement = event.target;
    const formSubmitter = event.submitter;
    console.log("The form element itself", formElement);
    console.log("The submitter of the form (usually an HtmlInputElement)", formSubmitter);

    const formData = new FormData(formElement);
    if(formSubmitter) formData.set(formSubmitter.name, formSubmitter.value);

    fetch(formElement.action, {
        method: formElement.method,
        body: formData,
    })

    event.preventDefault();
}

Note: check the compatibility of this feature.

Foumpie
  • 1,465
  • 1
  • 14
  • 10
  • 2
    This doesn't work in all browsers I tested it in, including Chrome and Firefox. You can submit a form by pressing enter, and the submitter returns the submit (button) element no matter what, not the element you were in and there is no way of telling whether it was a keypress or the element that triggered it. – cazort Nov 21 '21 at 01:39
0

Use submitter

event.nativeEvent.submitter would give you the button that initiated submit

submit(event){

    if (event.nativeEvent.submitter.id == "button2") { //do whatever }

}
Abraham
  • 12,140
  • 4
  • 56
  • 92