views:

828

answers:

4

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.

+2  A: 

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
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 <http://www.w3.org/TR/html5/forms.html#default-button>, 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
+1  A: 

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 j
That will unnecessarily break the button when JavaScript is unavailable.
bobince
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
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
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 j
Kooilnc, an <input type="button"> doesn't send anything to the server - its sole purpose is to trigger client-side code.
Stewart
A: 

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
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
Or should I say only option.
Chris Hynes
A: 

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