¿Cómo puedo obtener el botón que provocó el envío desde el evento de envío de formularios?

Estoy tratando de encontrar el valor del botón de enviar que activó el formulario para enviar

$("form").submit(function() { }); 

Podría disparar un evento $ (“input [type = submit]”). Click () para cada botón y establecer alguna variable, pero eso parece menos elegante que cómo se presiona el botón del formulario en el envío.

Aproveché document.activeElement como se bosqueja en esta respuesta: ¿Cómo obtener el elemento enfocado con jQuery?

 $form.on('submit', function() { var $btn = $(document.activeElement); if ( /* there is an activeElement at all */ $btn.length && /* it's a child of the form */ $form.has($btn) && /* it's really a submit element */ $btn.is('button[type="submit"], input[type="submit"], input[type="image"]') && /* it has a "name" attribute */ $btn.is('[name]') ) { console.log("Seems, that this element was clicked:", $btn); /* access $btn.attr("name") and $btn.val() for data */ } }); 

Aprovecho el hecho de que el botón siempre es el elemento enfocado después de hacer clic en él. Esto no funcionará si haces un blur() justo después del clic.

@Doin ha detectado otro inconveniente. Si un usuario envía el formulario a través de enter en un campo de texto, document.activeElement no está configurado. Debería tener cuidado con esto, al manejar eventos de keypress en la input[type="text"] y similares.

Actualización 2017-01: para mi Hyperform de la biblioteca, elegí no usar activeElement sino atrapar todos los eventos, que conducen al envío de formularios. El código para esto está en Github.

Si usa Hyperform, así es como accederá al botón que activó el envío:

 $(form).on('submit', function(event) { var button = event.submittedVia; }); 

Implementé esto y supongo que será suficiente.

 $(document).ready(function() { $("form").submit(function() { var val = $("input[type=submit][clicked=true]").val() // DO WORK }); 

y este es el evento de botón de envío que lo configura

 $("form input[type=submit]").click(function() { $("input[type=submit]", $(this).parents("form")).removeAttr("clicked"); $(this).attr("clicked", "true"); }); 

Gracias por las respuestas, pero esto no es terriblemente poco elegante …

Creé un formulario de prueba y el uso de Firebug encontrado de esta manera para obtener el valor;

 $('form').submit(function(event){ alert(event.originalEvent.explicitOriginalTarget.value); }); 

Lamentablemente, solo Firefox es compatible con este evento.

Aquí hay un enfoque que parece más limpio para mis propósitos.

Primero, para todas las formas:

 $('form').click(function(event) { $(this).data('clicked',$(event.target)) }); 

Cuando se activa este evento de clic para un formulario, simplemente registra el destino de origen (disponible en el objeto de evento) para acceder más tarde. Este es un trazo bastante amplio, ya que se disparará para cualquier clic en cualquier parte del formulario. Los comentarios de optimización son bienvenidos, pero sospecho que nunca causarán problemas notables.

Luego, en $ (‘formulario’). Submit (), puede preguntar qué fue lo último que se hizo clic, con algo como

 if ($(this).data('clicked').is('[name=no_ajax]')) xhr.abort(); 

De acuerdo con este enlace , el objeto Evento contiene un campo Event.target , que:

Devuelve una cadena que representa el objeto que inició el evento.

Acabo de crear una página que prueba qué es ese valor, y parece que esa representación es para el formulario en sí, no para el botón en el que se hizo clic. En otras palabras, Javascript no proporciona la facilidad para determinar el botón presionado.

En cuanto a la solución de Dave Anderson, podría ser una buena idea probar eso en múltiples navegadores antes de usarlo. Es posible que funcione bien, pero no puedo decirlo de ninguna manera.

Un enfoque limpio es usar el evento click en cada botón de formulario. A continuación se muestra un formulario html con los botones guardar, cancelar y eliminar:

 

Lo siguiente es el jquery. Envío la ‘acción’ apropiada a la misma función de servidor dependiendo de en qué botón se hizo clic (‘guardar’ o ‘eliminar’). Si se hace clic en ‘cancelar’, simplemente vuelvo a cargar la página.

 $('.savenote').click(function(){ var options = { data: {'action':'save'} }; $(this).parent().ajaxSubmit(options); }); $('.deletenote').click(function(){ var options = { data: {'action':'delete'} }; $(this).parent().ajaxSubmit(options); }); $('.cancelnote').click(function(){ window.location.reload(true); return false; }); 

Busqué y encontré varias formas de enviar el name botón de envío + value al servidor usando jQuery + AJAX. No me gustaron mucho …

¡Una de las mejores fue la solución de Hunter presentada aquí!

Pero escribí otro yo mismo.

Quiero compartir, porque es bueno y, como lo necesitaba, también funciona con formularios cargados mediante ajax (después de document.ready):

 $(document).on('click', 'form input[type=submit]', function(){ $('').appendTo($(this).parents('form').first()).attr('name', $(this).attr('name')).attr('value', $(this).attr('value')); }); 

¡Sencillo! Cuando se hace clic en el botón Enviar, se agrega un campo oculto al formulario, usando el mismo name y value del botón Enviar.

EDITAR: la siguiente versión es más fácil de leer. Además, se encarga de eliminar los campos ocultos previamente anexados (en el caso de enviar el mismo formulario dos veces, lo cual es perfectamente posible cuando se usa AJAX).

Código mejorado:

 $(document).on('click', 'form input[type=submit]', function(){ var name = $(this).attr('name'); if (typeof name == 'undefined') return; var value = $(this).attr('value'); var $form = $(this).parents('form').first(); var $input = $('').attr('name', name).attr('value', value); $form.find('input.temp-hidden').remove(); $form.append($input); }); 

Intenté algunos de los ejemplos proporcionados, pero no funcionaron para nuestros propósitos.

Aquí hay un violín para mostrar: http://jsfiddle.net/7a8qhofo/1/

Me enfrenté a un problema similar, y así es como resolvimos el problema en nuestros formularios.

 $(document).ready(function(){ // Set a variable, we will fill later. var value = null; // On submit click, set the value $('input[type="submit"]').click(function(){ value = $(this).val(); }); // On data-type submit click, set the value $('input[type="submit"][data-type]').click(function(){ value = $(this).data('type'); }); // Use the set value in the submit function $('form').submit(function (event){ event.preventDefault(); alert(value); // do whatever you need to with the content }); }); 

puede intentarlo de esta manera con “event.originalEvent.x” y “event.originalEvent.y”:

 < !DOCTYPE html>    test   





(evento)

 function submForm(form,event){ var submitButton; if(typeof event.explicitOriginalTarget != 'undefined'){ // submitButton = event.explicitOriginalTarget; }else if(typeof document.activeElement.value != 'undefined'){ // IE submitButton = document.activeElement; }; alert(submitButton.name+' = '+submitButton.value) } 

jQuery no parece proporcionar esa información en el evento de envío. Parece que el método que propusiste es tu mejor opción.

Otra solución más, ya que ninguna otra cumplía con mis requisitos. La ventaja es que se detectan clics y pulsaciones de teclas (introducir y espacio) .

 // Detects the Events var $form = $('form'); $form.on('click keypress', 'button[type="submit"]', function (ev) { // Get the key (enter, space or mouse) which was pressed. if (ev.which === 13 || ev.which === 32 || ev.type === 'click') { // Get the clicked button var caller = ev.currentTarget; // Input Validation if (!($form.valid())) { return; } // Do whatever you want, eg ajax... ev.preventDefault(); $.ajax({ // ... }) } } 

Esto funcionó mejor para mí.

Con un controlador de eventos más específico y JQuery, se hace clic en el objeto de su evento. También puede obtener la forma de delegación de este evento si es necesario.

 $('form').on('click', 'button', function (e) { e.preventDefault(); var $button = $(e.target), $form = $(e.delegateTarget); var buttonValue = $button.val(); }); 

Este documento tiene todo lo que necesitas para comenzar. JQuery Doc .