How can I get the button that caused the submit from the form submit event?

JqueryWebforms

Jquery Problem Overview


I'm trying to find the value of the submit button that triggered the form to submit

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

I could possibly fire a $("input[type=submit]").click() event for each button and set some variable, but that seems less elegant than some how pulling the button off of the the form on submit.

Jquery Solutions


Solution 1 - Jquery

I leveraged document.activeElement as sketched in this answer: https://stackoverflow.com/questions/11277989/how-to-get-the-focused-element-with-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 */
    }
});

I take advantage of the fact, that the button is always the focused element after clicking it. This will not work, if you do a blur() right after the click.

@Doin has spotted another drawback. If a user submits the form via enter in a text field, the document.activeElement is not set. You'd need to watch out for this yourself, by handling keypress events in input[type="text"] and similar.

Update 2017-01: For my library Hyperform I chose not to use activeElement but to catch all events, that lead to form submission. The code for this is on Github.

If you happen to use Hyperform, this is how you would access the button that triggered the submit:

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

Solution 2 - Jquery

I implemented this and I suppose it will do.

$(document).ready(function() {
    $("form").submit(function() { 

    var val = $("input[type=submit][clicked=true]").val()

    // DO WORK

});

and this is the submit button event that sets it up

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

Thanks for the responses, but this isn't terribly inelegant...

Solution 3 - Jquery

There is now a standard submitter property in the submit event.
Already implemented in Firefox 75 and Chrome/Edge 81 !

document.addEventListener('submit',function(e){
	console.log(e.submitter)
})

For browsers not supporting it, use this polyfill
Note: if you target older Browsers you need to polyfill other things like closest or matches. And ensure that the polyfill is loaded before adding your submit-events.

!function(){
    var lastBtn = null
    document.addEventListener('click',function(e){
        if (!e.target.closest) return;
        lastBtn = e.target.closest('button, input[type=submit]');
    }, true);
    document.addEventListener('submit',function(e){
        if ('submitter' in e) return;
		var canditates = [document.activeElement, lastBtn];
        lastBtn = null;
		for (var i=0; i < canditates.length; i++) {
			var candidate = canditates[i];
			if (!candidate) continue;
			if (!candidate.form) continue;
			if (!candidate.matches('button, input[type=button], input[type=image]')) continue;
			e.submitter = candidate;
			return;
		}
		e.submitter = e.target.querySelector('button, input[type=button], input[type=image]')
    }, true);
}();

Solution 4 - Jquery

I created a test form and using Firebug found this way to get the value;

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

Unfortunately, only Firefox supports this event.

Solution 5 - Jquery

Here's an approach that seems cleaner for my purposes.

First, for any and all forms:

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

When this click event is fired for a form, it simply records the originating target (available in the event object) to be accessed later. This is a pretty broad stroke, as it will fire for any click anywhere on the form. Optimization comments are welcome, but I suspect it will never cause noticeable issues.

Then, in $('form').submit(), you can inquire what was last clicked, with something like

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

Solution 6 - Jquery

According to this link, the Event object contains a field Event.target, which:

Returns a string representing the object that initiated the event.

I just created a page testing out what that value is, and it appears as though that representation is for the form itself, not for the button clicked. In other words, Javascript doesn't provide the facility to determine the clicked button.

As far as Dave Anderson's solution, it might be a good idea to test that in multiple browsers before using it. It's possible that it could work fine, but I can't say either way.

Solution 7 - Jquery

One clean approach is to use the click event on each form button. Following is a html form with save,cancel and delete buttons:

<form  name="formname" action="/location/form_action" method="POST">
<input name="note_id" value="some value"/>
<input class="savenote" type="submit" value="Save"/>
<input class="cancelnote" type="submit" value="Cancel"/>
<input class="deletenote" type="submit" value="Delete" />
</form> 

Following is the jquery. I send the appropriate 'action' to the same server function depending on which button was clicked ('save' or 'delete'). If 'cancel', is clicked, I just reload the page.

$('.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;
   });


Solution 8 - Jquery

There's a submitter property for form's SubmitEvent. However, as of present time, this doesn't work on Safari.

<form id="form">
    <button value="add" type="submit">Add</button>
    <button value="remove" type="submit">Remove</button>
</form>
let form = document.getElementById('form');

form.onsubmit = (event) => {
    e.preventDefault();
    console.log(e.submitter.type);
}

A different approach that works across browsers. However, you have to rely on form element instead of the event object. This basically adds a 'submitter' property onto the form element object that can be referenced later on form submit.

<form id="form">
    <button onclick="this.form.submitter = 'add'" type="submit">Add</button>
    <button onclick="this.form.submitter = 'remove'" type="submit">Remove</button>
</form>
let form = document.getElementById('form');

form.onsubmit = (event) => {
    e.preventDefault();
    console.log(form.submitter);
}

Solution 9 - Jquery

I searched and found several ways to get the submit button name + value sent to the server using jQuery + AJAX. I didn't like them very much...

One of the bests was hunter's solution presented here!

But I wrote another one myself.

I want to share, because it is good, and, as I needed, it works also with forms loaded via ajax (after document.ready):

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

Simple! When the submit button is clicked, a hidden field is added to the form, using same name and value of the submit button.

EDIT: The version below is easier to read. Also, it takes care of removing previously appended hidden fields (in the case of submitting the same form twice, which is perfectly possible when using AJAX).

Improved code:

$(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 = $('<input type="hidden" class="temp-hidden" />').attr('name', name).attr('value', value);
	$form.find('input.temp-hidden').remove();
	$form.append($input);
});

Solution 10 - Jquery

( event )

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


<form action="" method="post" onSubmit="submForm(this, event); return false;">

Solution 11 - Jquery

I did try some of the examples provided, but they didn't work for our purposes.

Here's a fiddle to show: http://jsfiddle.net/7a8qhofo/1/

I was faced with a similar issue, and this is how we solved the issue in our forms.

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

Solution 12 - Jquery

Get the submitter object from the event object

You can simply get the event object when you submit the form. From that, get the submitter object. As below:

$(".review-form").submit(function (e) {
		e.preventDefault(); // avoid to execute the actual submit of the form.

		let submitter_btn = $(e.originalEvent.submitter);
		
		console.log(submitter_btn.attr("name"));
}

I have explained in detailed wat here: (https://stackoverflow.com/a/66334184/11320178)
Let me know if you have any doubts.

Solution 13 - Jquery

you can try this way with "event.originalEvent.x" and "event.originalEvent.y":

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
	<title>test</title>
</head>
<body>
	
	<form id="is_a_form">
		<input id="is_a_input_1" type="submit"><br />
		<input id="is_a_input_2" type="submit"><br />
		<input id="is_a_input_3" type="submit"><br />
		<input id="is_a_input_4" type="submit"><br />
		<input id="is_a_input_5" type="submit"><br />
	</form>
	
</body>
</html>
<script>
$(function(){

	$.fn.extend({
	  inPosition: function(x, y) {
	  	
	    return this.each(function() {
	    	
	    	try{
		    	var offset = $(this).offset();
		    	
		    	if ( (x >= offset.left) &&
		    	     (x <= (offset.left+$(this).width())) &&
		    	     (y >= offset.top) &&
		    	     (y <= (offset.top+$(this).height())) )
		    	{
			    	$(this).css("background-color", "red");
			    }
			    else
		    	{
						$(this).css("background-color", "#d4d0c8");
		    	}
				}
				catch(ex)
				{
				}
						    
	    });
	  }
	});	

	$("form").submit(function(ev) {
		
		$("input[type='submit']").inPosition(ev.originalEvent.x ,ev.originalEvent.y);
		return false;
	
	});

});
</script>

Solution 14 - Jquery

jQuery doesn't seem to provide that data on the submit event. Looks like the method you proposed is your best bet.

Solution 15 - Jquery

Just another solution since no other met my requirements. The advantage is, that click and keypress (enter and space) are detected.

// 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, e.g. ajax...
        ev.preventDefault();
        $.ajax({
            // ...
        })
    }
}

This worked best for me.

Solution 16 - Jquery

With a more specific event handler and JQuery, your event object is the button clicked. You can also get the delegating form from this event if needed.

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

This Doc has everything you need to get started. JQuery Doc.

Solution 17 - Jquery

I write this function that helps me

var PupulateFormData= function (elem) {
    var arr = {};
    $(elem).find("input[name],select[name],button[name]:focus,input[type='submit']:focus").each(function () {
        arr[$(this).attr("name")] = $(this).val();
    });
    return arr;

};

and then Use

var data= PupulateFormData($("form"));

Solution 18 - Jquery

In working with web components where form elements are in the shadowRoot I adapted Tobias Buschor's excellent polyfill as follows to work in the following way via an imported module. Note this only provides compatibility in evergreen clients--edge, safari, chrome, firefox. Also, as noted by Mikko Rantalainen, this doesn't follow (and I/we can update at some point to follow) https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-form-submit

if( !('SubmitEvent' in self && 'submitter' in SubmitEvent.prototype) ){
// polyfill SubmitEvent.submitter (a Safari issue as-of 2021)
// https://developer.mozilla.org/docs/Web/API/SubmitEvent
	const submitter = Symbol.for('submitter');
	Event[ submitter ] = null;
	const submitterSelector = 'input[type=submit], input[type=image], input[type=button], button';

	Object.defineProperty(Event.prototype, 'submitter', {
		get: function(){
			if('submit' === this.type){
				let node = Event[ submitter ];
				const form = this.target;
				if(!node || !form.contains(node)){
					node = form.querySelector(submitterSelector);
				}
				// always return a node, default as though form.submit called
				return node || form;
			}
			return undefined;
		},
		set: function(value){
			if('submit' === this.type){
				this.submitter = value;
			}
		}
	});
	self.addEventListener('click', function polyfill_SubmitEvent_submitter_click(event){
		const node = event.composedPath()[0];
		const closest = node.closest?.(submitterSelector) ?? null;
		Event[ submitter ] = closest;
	}, true);
}

Solution 19 - Jquery

$(document).ready(function() {
    $( "form" ).submit(function (event) {
        // Get the submit button element
        let submit_button =  event.handleObj;
        //submit button has the object of the use clicked button
    });
}

Solution 20 - Jquery

You can obtain the button id of the following HTML code:

<form id="theForm" action="" method="POST">
  <button name="sbtn" id="sbtn" value="Hey button" type="submit">Submit</button>
</form>

using the following JavaScript (leveraging on the .val() attribute):

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

Solution 21 - Jquery

Without jquery

submit(e){
	console.log(e.nativeEvent.submitter)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhunterView Question on Stackoverflow
Solution 1 - JqueryBoldewynView Answer on Stackoverflow
Solution 2 - JqueryhunterView Answer on Stackoverflow
Solution 3 - JqueryTobias BuschorView Answer on Stackoverflow
Solution 4 - JqueryDave AndersonView Answer on Stackoverflow
Solution 5 - JqueryJonathan CamenischView Answer on Stackoverflow
Solution 6 - JquerycmptrgeekkenView Answer on Stackoverflow
Solution 7 - Jqueryuser1128563View Answer on Stackoverflow
Solution 8 - JqueryNur IlyasView Answer on Stackoverflow
Solution 9 - JqueryJ. BruniView Answer on Stackoverflow
Solution 10 - Jqueryuser3126867View Answer on Stackoverflow
Solution 11 - JqueryRudi StrydomView Answer on Stackoverflow
Solution 12 - JqueryKarishma SukhwaniView Answer on Stackoverflow
Solution 13 - Jqueryandres descalzoView Answer on Stackoverflow
Solution 14 - JqueryMatchuView Answer on Stackoverflow
Solution 15 - JqueryrolandView Answer on Stackoverflow
Solution 16 - Jqueryuser8205152View Answer on Stackoverflow
Solution 17 - JqueryBabiBNView Answer on Stackoverflow
Solution 18 - JqueryjimmontView Answer on Stackoverflow
Solution 19 - JqueryJiffinView Answer on Stackoverflow
Solution 20 - JqueryGeorge mView Answer on Stackoverflow
Solution 21 - JqueryAbrahamView Answer on Stackoverflow