views:

36

answers:

4

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 asyncrhnous 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 FF has evnt.explicitOriginalTarget but I can't find anything for other browsers.

A: 

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
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
Hidden Fields? For what?
Dutchie432
#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
Good Catch. Reversed the order of the calls.
Dutchie432
A: 

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
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
All right. But, I guess I'm not sure exactly what you want to do, then.
palswim
A: 

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"&gt;&lt;/script&gt;
  <script type="text/javascript">
  $(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];
      }

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

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