12

Is there a way to determine which element submitted a form from within an onsubmit handler? Trying to write a generic handler that knows which element was clicked. For example, given this form:

<form onsubmit="onSubmitHandler">
    <input type="submit" name="submit1" />
    <input type="submit" name="submit2" />
</form>

How can I determine inside the onSubmitHandler which submit button was clicked? I tried event.target/event.srcElement, but that gives the form, not the actual submit button.

Update: I'm writing a generic control here, so it has no idea what's on the form. The solution needs to work without knowing and changing the html of the form. My fallback is walking the DOM to find all buttons that could cause a submit, but I'd like to avoid that.

Chris Hynes
  • 9,999
  • 2
  • 44
  • 54
  • There's no guaranty that any submit buttons have been clicked. E.g. Submitting by JS (form.submit()) will result in no buttons value being included in the post back – Rune FS Nov 15 '10 at 09:06
  • That's fine too. A little more background on the problem: this is for an AJAX component. I'm cancelling the first submit, doing my own thing, and then I need to rerun the first submit as it happened, with all the correct form values. As far as I've been able to determine, the only way to do this is to walk the DOM and add click handlers to anything that could cause a submit, and then save that. Assume the last thing that was clicked was the thing that submitted the form, and then call .click() on it when I need to resubmit the form. – Chris Hynes Dec 01 '10 at 20:24

5 Answers5

3

An alternative solution would be to move the event trigger from the form's submit event, to the submit element's onclick event, as such:

<form name='form1'>  
    <input type="submit" name="submit1" onclick="onSubmitHandler"/>
    <input type="submit" name="submit2" onclick="onSubmitHandler"/>
</form>

In your handler function you can determine the submitting element simply by inspecting the event target's name, and if you need access to the form's information or other elements, you can get this from the submit elements "form" attribute.

Joseph Tary
  • 1,391
  • 1
  • 8
  • 5
  • 2
    You'd still need an onsubmit handler in addition to these, since it's possible for a submit event to take place without a button being pressed. The spec leaves semi-open the question of which button (if any) is activated by pressing Enter while focused on a non-button control , and browsers aren't consistent (though by my experiments, it seems to be either the first button on the form or none at all). – Stewart Jun 01 '09 at 11:20
1

I would not use a standard submit button-type.

Make the submit function take an extra argument which represents the element that submitted it, and the button would have an onclick that sends this as the parameter:

<input type="button" onclick="submitHandler(this)">
hasen
  • 161,647
  • 65
  • 194
  • 231
  • That will unnecessarily break the button when JavaScript is unavailable. – bobince Feb 12 '09 at 16:53
  • The button will still work without js, but then the only method to determine te actual button pressed will be a server side one. You can do that by giving the button a value, by the way. – KooiInc Feb 12 '09 at 18:22
  • This needs to be all client side. I don't care about the server in this case. It also needs to be generic -- I don't have access to the page html. – Chris Hynes Feb 12 '09 at 21:57
  • 1
    Renzo, what does server side have to do with this?? This *is* generic, but to a certain level, the only thing is that it will force the submit button to identify itself explicitly. bobince, I think you can fallback to html by making type="submit" and adding "return false" at the end of the onclick – hasen Feb 12 '09 at 23:29
  • 2
    Kooilnc, an doesn't send anything to the server - its sole purpose is to trigger client-side code. – Stewart Aug 17 '09 at 11:44
0

Click events bubble, so you could just add an "onclick" listener to the form itself, that checks if the click target source is a submit button; if so, store a reference to it somewhere associated with the form that you can access from your onsubmit handler.

If you want to handle "Enter"-submitted forms properly too, listen to the form's "onkeypress" or "onkeydown" event, check for "Enter", and clear your submit-button info if the event target ISN'T a submit button.

Doin
  • 7,545
  • 4
  • 35
  • 37
0

My fallback is walking the DOM to find all buttons that could cause a submit, but I'd like to avoid that.

...and adding click listeners to them to store the ‘last clicked’ button which is then read by the submit listener, right?

I can't think of any other way, sorry.

bobince
  • 528,062
  • 107
  • 651
  • 834
  • Yes, exactly. It's brittle because if something else on the page adds a submit button after I hook it'll break. But that seems to be the best option, unfortunately. – Chris Hynes Feb 12 '09 at 16:56
0

This solution works in Firefox. I haven't checked it in other compliant browsers or IE.
I'm not too hopeful for IE, you'd have to look into it and post your results.

<form id="myForm">
    <input type="submit">
    <input type="submit">
</form>

_

document.getElementById('myForm').addEventListener( 'submit', function( e ){
    e.preventDefault();
    e.explicitOriginalTarget.style.background = 'red';
}, false );
meouw
  • 41,754
  • 10
  • 52
  • 69
  • That's pretty sweet, but it looks like a no on the crossbrowser: http://stackoverflow.com/questions/179826/crossbrowser-equivalent-of-explicitoriginaltarget-event-parameter, and unfortunately this needs to handle the big 4 browsers, so that one is out. – Chris Hynes Feb 12 '09 at 17:06
  • January 2019 and explicitOriginalTarget is still non-standard [according to MDN](https://developer.mozilla.org/en-US/docs/Web/API/Event/explicitOriginalTarget). – faintsignal Feb 02 '19 at 02:10