2010-08-26 35 views
74

Tengo un formulario con dos botones de envío y algo de código:Formulario onSubmit determinar qué botón de envío se presiona

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

Por supuesto los dos submit botones lograr cosas diferentes. ¿Hay alguna forma de averiguar en onSubmit qué botón se presionó, para poder enviarlo más tarde al thatButton.click()?

Idealmente, me gustaría no modificar el código de los botones, solo tengo un complemento de JavaScript puro que tiene este comportamiento.

Sé que FF tiene evnt.explicitOriginalTarget pero no puedo encontrar nada para otros navegadores.

+6

creo que esto no se duplica, la otra pregunta es en el contexto de jQuery, mientras que éste no es, ver mi respuesta a continuación. –

+6

De acuerdo, Javascript! = JQuery. – Jon

+1

NO es un duplicado..por favor, vuelva a preguntar. – AKS

Respuesta

37

No en el controlador de eventos submit, no.

Pero lo que puede hacer es agregar manejadores de clics a cada envío que informará al manejador de envío de que se hizo clic.

Aquí hay un ejemplo completo (usando jQuery para mayor brevedad)

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

... como alternativa, puede captar los clics cuando burbujean, agregando un controlador onclick al formulario mismo, que comprueba si el elemento cliqueado fue un botón de envío; esto podría ser más simple en algunos casos. – Doin

+0

@Doin ¿Un ejemplo? – JeromeJ

+0

@JeromeJ: Editó esta respuesta para incluir un ejemplo; esperemos que la revisión por pares lo permita. (Lo habría publicado como mi propia respuesta, pero la pregunta está cerrada). – Doin

7

primera sugerencia:

crear una variable de Javascript que referenciará el botón pulsado. Deja llamada que buttonIndex

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

Ahora, puede acceder a ese valor. 0 significa que se hizo clic en el botón Guardar, 1 significa que se hizo clic en el botón GuardarAñadir.

segunda sugerencia

La forma en que iba a manejar esto es para crear dos funciones JS que manejan cada uno de los dos botones.

Primero, asegúrese de que su formulario tenga una identificación válida. Para este ejemplo, voy a decir el ID es "myForm"

cambio

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

a

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

el retorno (falso) para evitar que su sumisión de la forma de realidad procesamiento, y llame a sus funciones personalizadas, donde puede enviar el formulario más tarde.

A continuación, sus funciones van a trabajar algo como esto ...

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(); 
    } 
} 
+0

Tipo de. Tendría que agregar campos ocultos en cada una de las funciones de envío, uno con nombre = "guardar" valor = "..." y etc. y estoy tratando de evitar eso. No me malinterprete, es una solución válida. Solo estoy buscando algo más elegante. – McTrafik

+0

¿Campos ocultos? ¿Para qué? – Dutchie432

+0

# 2 no funcionará: cuando utilizó manejadores de eventos basados ​​en DOM, nada se ejecutará después de una instrucción 'return'. Por lo tanto, sus llamadas a 'submitFunc()' y 'submitAndAddFunc()' nunca se activarán. –

0

¿Por qué no han de enlazarse a través de las entradas y luego agregar controladores onclick a cada uno?

Usted no tiene que hacerlo en HTML, pero se puede agregar un controlador a cada botón:

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

Luego, su función podría "hacer cosas", de acuerdo a lo que el valor que se pasa:

function DoStuff(val) { 
    if(val === "Val 1") { 
     // Do some stuff 
    } 
    // Do other stuff 
} 
+0

La única forma en que puedo pensar en hacer esto es estableciendo algún tipo de variable global con el último botón de entrada presionado. Esa no es una mala idea. – McTrafik

+0

De acuerdo. Pero, supongo que no estoy seguro exactamente de lo que quieres hacer, entonces. – palswim

0

utilizo Ext, por lo que terminó haciendo esto:

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]); 
} 

y luego, cuando ya era hora de presentar hice

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

Espera, dices. Esto funcionará si no tienes cuidado. Así, onSubmit a veces debe volver verdaderos

// 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; 
} 
36
<form onsubmit="alert(this.submited); return false;"> 
    <input onclick="this.form.submited=this.value;" type="submit" value="Yes" /> 
    <input onclick="this.form.submited=this.value;" type="submit" value="No" /> 
</form> 
+1

@McLosysCreative gracias, actualizado. http://jsfiddle.net/dj3QE/ –

12

sencillísimas, pero confirmó trabajo, ejemplo:

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

Todas las respuestas anteriores son muy buenas, pero me lo limpió un poco.

Esta solución coloca automáticamente el nombre del botón de envío presionado en el campo de acción oculta. Tanto el javascript en la página como el código del servidor pueden verificar el valor del campo oculto de acción según sea necesario.

La solución utiliza jquery para aplicarse automáticamente a todos los botones de envío.

<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();" /> 

Luego escriba un código como este en su controlador de envío de formularios.

if ($("#action").val() == "delete") { 
    return confirm("Are you sure you want to delete the selected item?"); 
} 
+0

Esto depende del evento click que se maneja antes de enviar el formulario. ¿Siempre será ese el caso? Para formularios cargados dinámicamente en diálogos modales, tendría que usar un controlador delegado y debería adjuntarlo para que use el destino del evento para descubrir qué formulario contiene el elemento al que se hace clic y asegurarse de que el campo oculto al que se dirige esté dentro esa forma. – Triynko

2

OP declaró que no quería modificar el código de los botones. Esta es la respuesta menos intrusiva que podría llegar a usar las otras respuestas como guía. No requiere campos ocultos adicionales, le permite dejar intacto el código del botón (a veces no tiene acceso a lo que lo genera), y le brinda la información que estaba buscando desde cualquier parte de su código ... qué botón fue utilizado para enviar el formulario. No he evaluado qué sucede si el usuario usa la tecla Intro para enviar el formulario, en lugar de hacer clic.

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

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

</script> 

Luego tiene acceso a la variable 'iniciador' en cualquier lugar que pueda necesitar hacer la comprobación. Espero que esto ayude.

~ Spanky

Cuestiones relacionadas