114

I have a form with two submit buttons and some code:

HTML:

<input type="submit" name="save" value="Save" />
<input type="submit" name="saveAndAdd" value="Save and add another" />

JavaScript:

form.onSubmit = function(evnt) {
    // Do some asynchronous stuff, that will later on submit the form
    return false;
}

Of course the two submit buttons accomplish different things. Is there a way to find out in onSubmit which button was pressed, so later I could submit by doing thatButton.click()?

Ideally I would like to not modify the code for the buttons, just have a pure JavaScript addon that has this behavior.

I know that Firefox has evnt.explicitOriginalTarget, but I can't find anything for other browsers.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
McTrafik
  • 2,843
  • 3
  • 29
  • 31
  • https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter switch evnt. submitter.name ... – Flo Aug 10 '22 at 13:35

8 Answers8

70
<form onsubmit="alert(this.submitted); return false;">
    <input onclick="this.form.submitted=this.value;" type="submit" value="Yes" />
    <input onclick="this.form.submitted=this.value;" type="submit" value="No" />
</form>

jsfiddle for the same

Ali Shakiba
  • 20,549
  • 18
  • 61
  • 88
  • 2
    This solution is simple, elegant, and easy to implement; why anyone would prefer Peter Bailey's solution, which is extremely cumbersome and requires jquery (which the original question DID NOT specify) is beyond me. – cazort Mar 14 '19 at 19:45
  • 4
    This won't work if the form was submitted by the user pressing enter – 99 Problems - Syntax ain't one Aug 08 '19 at 11:58
  • 2
    @99Problems-Syntaxain'tone because enter is not a submit button on the screen and is not a requirement at all? – Avin Kavish Apr 16 '20 at 04:42
  • 1
    How does this work? I can't figure out what is "this.form.submited". How am I accessing the form from within the button object? – Lukas Aug 12 '20 at 16:59
43

Not in the submit event handler itself, no.

But what you can do is add click handlers to each submit which will inform the submit handler as to which was clicked.

Here's a full example (using jQuery for brevity)

<html>
<head>
  <title>Test Page</title>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript">

  jQuery(function($) {
      var submitActor = null;
      var $form = $('#test');
      var $submitActors = $form.find('input[type=submit]');

      $form.submit(function(event) {
          if (null === submitActor) {
              // If no actor is explicitly clicked, the browser will
              // automatically choose the first in source-order
              // so we do the same here
              submitActor = $submitActors[0];
          }

          console.log(submitActor.name);
          // alert(submitActor.name);

          return false;
      });

      $submitActors.click(function(event) {
          submitActor = this;
      });
  });

  </script>
</head>

<body>

  <form id="test">

    <input type="text" />

    <input type="submit" name="save" value="Save" />
    <input type="submit" name="saveAndAdd" value="Save and add another" />

  </form>

</body>
</html>
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206
  • 3
    ...alternatively you catch the clicks as they bubble, by adding an onclick handler to the form itself, that checks if the clicked element was a submit button; this might be simpler in some cases. – Doin May 11 '13 at 18:35
  • @JeromeJ: Edited this answer to include example; hopefully peer-review will allow it through. (I'd have posted it as my own answer, but the question is closed). – Doin Jun 14 '14 at 05:28
  • 1
    @Peter, If you check for clicks, what happens when they "press" the submit button using Enter key or something else altogether? (It still works on Chrome, but) Is there a standard behavior? – Pacerier Mar 01 '15 at 23:51
  • I'm not 100% up-to-date on the current compatibilities, but generally speaking, I'd say don't check for clicks if it's not actually a click that matters. – Peter Bailey Mar 03 '15 at 16:18
  • 3
    The original question doesn't mention or reference jquery. Many of us don't want to use jquery. – cazort Mar 14 '19 at 19:07
  • @PeterBailey I have the same scenario but the only change is I have type button and from its clicked event I submit the form then how can I get the button name? please help me Thanks – Sachin Sarola Feb 18 '20 at 06:20
  • This is no longer true, we now have a submitter property ! https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter – kigiri Aug 22 '22 at 07:49
29

Bare bones, but confirmed working, example:

<script type="text/javascript">
var clicked;
function mysubmit() {
    alert(clicked);
}
</script>
<form action="" onsubmit="mysubmit();return false">
    <input type="submit" onclick="clicked='Save'" value="Save" />
    <input type="submit" onclick="clicked='Add'" value="Add" />
</form>
Henrik
  • 287
  • 3
  • 2
20

All of the answers above are very good but I cleaned it up a little bit.

This solution automatically puts the name of the submit button pressed into the action hidden field. Both the javascript on the page and the server code can check the action hidden field value as needed.

The solution uses jquery to automatically apply to all submit buttons.

<input type="hidden" name="action" id="action" />
<script language="javascript" type="text/javascript">
    $(document).ready(function () {
        //when a submit button is clicked, put its name into the action hidden field
        $(":submit").click(function () { $("#action").val(this.name); });
    });
</script>
<input type="submit" class="bttn" value="<< Back" name="back" />
<input type="submit" class="bttn" value="Finish" name="finish" />
<input type="submit" class="bttn" value="Save" name="save" />
<input type="submit" class="bttn" value="Next >>" name="next" />
<input type="submit" class="bttn" value="Delete" name="delete" />
<input type="button" class="bttn" name="cancel" value="Cancel" onclick="window.close();" />

Then write code like this into your form submit handler.

 if ($("#action").val() == "delete") {
     return confirm("Are you sure you want to delete the selected item?");
 }
Ben Gripka
  • 16,012
  • 6
  • 45
  • 41
  • This depends on the click event being handled before the form is submitted. Will that always be the case? For forms loaded dynamically in modal dialogs, you'd have to use a delegated handler and would have to attach it so that it uses the event target to figure out which form contains the clicked element and ensure the hidden field you're targeting is inside that form. – Triynko Nov 30 '15 at 06:30
8

First Suggestion:

Create a Javascript Variable that will reference the button clicked. Lets call it buttonIndex

<input type="submit" onclick="buttonIndex=0;" name="save" value="Save" />
<input type="submit" onclick="buttonIndex=1;" name="saveAndAdd" value="Save and add another" />

Now, you can access that value. 0 means the save button was clicked, 1 means the saveAndAdd Button was clicked.

Second Suggestion

The way I would handle this is to create two JS functions that handle each of the two buttons.

First, make sure your form has a valid ID. For this example, I'll say the ID is "myForm"

change

<input type="submit" name="save" value="Save" />
<input type="submit" name="saveAndAdd" value="Save and add another" />

to

<input type="submit" onclick="submitFunc();return(false);" name="save" value="Save" />
<input type="submit" onclick="submitAndAddFunc();return(false);" name="saveAndAdd" value="Save and add 

the return(false) will prevent your form submission from actually processing, and call your custom functions, where you can submit the form later on.

Then your functions will work something like this...

function submitFunc(){
    // Do some asyncrhnous stuff, that will later on submit the form
    if (okToSubmit) {
        document.getElementById('myForm').submit();
    }
}
function submitAndAddFunc(){
    // Do some asyncrhnous stuff, that will later on submit the form
    if (okToSubmit) {
        document.getElementById('myForm').submit();
    }
}
Dutchie432
  • 28,798
  • 20
  • 92
  • 109
  • Sort-of. I would have to then add hidden fields in each one of the submit functions, one with name="save" value="..." and etc. and I'm trying to avoid that. Don't get me wrong it's a valid solution. I'm just looking for something more elegant. – McTrafik Aug 26 '10 at 17:05
  • Hidden Fields? For what? – Dutchie432 Aug 26 '10 at 17:08
  • #2 won't work - when you used DOM-based event handlers, nothing will be executed after a `return` statement. So your calls to `submitFunc()` and `submitAndAddFunc()` will never fire. – Peter Bailey Aug 26 '10 at 17:17
  • Good Catch. Reversed the order of the calls. – Dutchie432 Aug 26 '10 at 17:36
6

OP stated he didn't want to modify the code for the buttons. This is the least-intrusive answer I could come up with using the other answers as a guide. It doesn't require additional hidden fields, allows you to leave the button code intact (sometimes you don't have access to what generates it), and gives you the info you were looking for from anywhere in your code...which button was used to submit the form. I haven't evaluated what happens if the user uses the Enter key to submit the form, rather than clicking.

<script language="javascript" type="text/javascript">

    var initiator = '';
    $(document).ready(function() {
        $(":submit").click(function() { initiator = this.name });
    });

</script>

Then you have access to the 'initiator' variable anywhere that might need to do the checking. Hope this helps.

~Spanky

Spanky
  • 5,608
  • 10
  • 39
  • 45
1

I use Ext, so I ended up doing this:

var theForm = Ext.get("theform");
var inputButtons = Ext.DomQuery.jsSelect('input[type="submit"]', theForm.dom);
var inputButtonPressed = null;
for (var i = 0; i < inputButtons.length; i++) {
    Ext.fly(inputButtons[i]).on('click', function() {
        inputButtonPressed = this;
    }, inputButtons[i]);
}

and then when it was time submit I did

if (inputButtonPressed !== null) inputButtonPressed.click();
else theForm.dom.submit();

Wait, you say. This will loop if you're not careful. So, onSubmit must sometimes return true

// Notice I'm not using Ext here, because they can't stop the submit
theForm.dom.onsubmit = function () {
    if (gottaDoSomething) {
        // Do something asynchronous, call the two lines above when done.
        gottaDoSomething = false;
        return false;
    }
    return true;
}
McTrafik
  • 2,843
  • 3
  • 29
  • 31
0

Why not loop through the inputs and then add onclick handlers to each?

You don't have to do this in HTML, but you can add a handler to each button like:

button.onclick = function(){ DoStuff(this.value); return false; } // return false; so that form does not submit

Then your function could "do stuff" according to whichever value you passed:

function DoStuff(val) {
    if( val === "Val 1" ) {
        // Do some stuff
    }
    // Do other stuff
}
palswim
  • 11,856
  • 6
  • 53
  • 77
  • The only way I can think of doing this is by setting some sort of global variable with the last input button pressed. That's not a bad idea. – McTrafik Aug 26 '10 at 17:07
  • All right. But, I guess I'm not sure exactly what you want to do, then. – palswim Aug 26 '10 at 17:10