jQuery: how to get which button was clicked upon form submission?

JqueryForms

Jquery Problem Overview


I have a .submit() event set up for form submission. I also have multiple forms on the page, but just one here for this example. I'd like to know which submit button was clicked without applying a .click() event to each one.

Here's the setup:

<html>
<head>
  <title>jQuery research: forms</title>
  <script type='text/javascript' src='../jquery-1.5.2.min.js'></script>
  <script type='text/javascript' language='javascript'>
      $(document).ready(function(){
          $('form[name="testform"]').submit( function(event){ process_form_submission(event); } );
      });
      function process_form_submission( event ) {
          event.preventDefault();
          //var target = $(event.target);
          var me = event.currentTarget;
          var data = me.data.value;
          var which_button = '?';       // <-- this is what I want to know
          alert( 'data: ' + data + ', button: ' + which_button );
      }
  </script>
</head>
<body>
<h2>Here's my form:</h2>
<form action='nothing' method='post' name='testform'>
  <input type='hidden' name='data' value='blahdatayadda' />
  <input type='submit' name='name1' value='value1' />
  <input type='submit' name='name2' value='value2' />
</form>
</body>
</html>

http://jsfiddle.net/fKppt/">Live example on jsfiddle

Besides applying a .click() event on each button, is there a way to determine which submit button was clicked?

Jquery Solutions


Solution 1 - Jquery

I asked this same question: https://stackoverflow.com/questions/2066162/how-can-i-get-the-button-that-caused-the-submit-from-the-form-submit-event

I ended up coming up with this solution and it worked pretty well:

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

In your case with multiple forms you may need to tweak this a bit but it should still apply

Solution 2 - Jquery

I found that this worked.

$(document).ready(function() {
    $( "form" ).submit(function () {
        // Get the submit button element
        var btn = $(this).find("input[type=submit]:focus" );
    });
}

Solution 3 - Jquery

This works for me:

$("form").submit(function() {
   // Print the value of the button that was clicked
   console.log($(document.activeElement).val());
}

Solution 4 - Jquery

When the form is submitted:

  • document.activeElement will give you the submit button that was clicked.

  • document.activeElement.getAttribute('value') will give you that button's value.

Note that if the form is submitted by hitting the Enter key, then document.activeElement will be whichever form input that was focused at the time. If this wasn't a submit button then in this case it may be that there is no "button that was clicked."

Solution 5 - Jquery

Here's the 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

Wow... nice to see too many solutions here. but there was a native Javascript property submitter on the SubmitEvent interface. https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter

Native Javascript

var btnClicked = event.submitter;

JQuery version

var btnClicked = event.originalEvent.submitter;

Solution 7 - Jquery

Wow, some solutions can get complicated! If you don't mind using a simple global, just take advantage of the fact that the input button click event fires first. One could further filter the $('input') selector for one of many forms by using $('#myForm input').

    $(document).ready(function(){
      var clkBtn = "";
      $('input[type="submit"]').click(function(evt) {
        clkBtn = evt.target.id;
      });
	
      $("#myForm").submit(function(evt) {
        var btnID = clkBtn;
        alert("form submitted; button id=" + btnID);
      });
    });

Solution 8 - Jquery

I have found the best solution is

$(document.activeElement).attr('id')

This not only works on inputs, but it also works on button tags. Also it gets the id of the button.

Solution 9 - Jquery

Another possible solution is to add a hidden field in your form:

<input type="hidden" id="btaction"/>

Then in the ready function add functions to record what key was pressed:

$('form#myForm #btnSubmit').click(function() {
    $('form#myForm #btaction').val(0);
});

$('form#myForm #btnSubmitAndSend').click(function() {
    $('form#myForm #btaction').val(1);
});

$('form#myForm #btnDelete').click(function() {
    $('form#myForm #btaction').val(2);
});

Now in the form submition handler read the hidden variable and decide based on it:

var act = $('form#myForm #btaction').val();

Solution 10 - Jquery

Building on what Stan and yann-h did but this one defaults to the first button. The beauty of this overall approach is that it picks up both the click and the enter key (even if the focus was not on the button. If you need to allow enter in the form, then just respond to this when a button is focused (i.e. Stan's answer). In my case, I wanted to allow enter to submit the form even if the user's current focus was on the text box.

I was also using a 'name' attribute rather than 'id' but this is the same approach.

var pressedButtonName =
     typeof $(":input[type=submit]:focus")[0] === "undefined" ?
     $(":input[type=submit]:first")[0].name :
     $(":input[type=submit]:focus")[0].name;

Solution 11 - Jquery

This one worked for me

$('#Form').submit(function(){
var btn= $(this).find("input[type=submit]:focus").val();
alert('you have clicked '+ btn);

}

Solution 12 - Jquery

Here is my solution:

   $('#form').submit(function(e){   
        console.log($('#'+e.originalEvent.submitter.id));
	    e.preventDefault();
	});

Solution 13 - Jquery

If what you mean by not adding a .click event is that you don't want to have separate handlers for those events, you could handle all clicks (submits) in one function:

$(document).ready(function(){
  $('input[type="submit"]').click( function(event){ process_form_submission(event); } );
});

function process_form_submission( event ) {
  event.preventDefault();
  //var target = $(event.target);
  var input = $(event.currentTarget);
  var which_button = event.currentTarget.value;
  var data = input.parents("form")[0].data.value;
//  var which_button = '?';       // <-- this is what I want to know
  alert( 'data: ' + data + ', button: ' + which_button );
}

Solution 14 - Jquery

As I can't comment on the accepted answer, I bring here a modified version that should take into account elements that are outside the form (ie: attached to the form using the form attribute). This is for modern browser: http://caniuse.com/#feat=form-attribute . The closest('form') is used as a fallback for unsupported form attribute

$(document).on('click', '[type=submit]', function() {
    var form = $(this).prop('form') || $(this).closest('form')[0];
    $(form.elements).filter('[type=submit]').removeAttr('clicked')
    $(this).attr('clicked', true);
});

$('form').on('submit', function() {
    var submitter = $(this.elements).filter('[clicked]');
})

Solution 15 - Jquery

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

In case you want to send this form to the backend, you can create a new form element by new FormData() and set the key-value pair for which button was pressed, then access it in the backend. Something like this -

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

		let form = $(this);
		let newForm = new FormData($(form)[0]);
		let submitter_btn = $(e.originalEvent.submitter);
		
		console.log(submitter_btn.attr("name"));

        if (submitter_btn.attr("name") == "approve_btn") {
			newForm.set("action_for", submitter_btn.attr("name"));
		} else if (submitter_btn.attr("name") == "reject_btn") {
			newForm.set("action_for", submitter_btn.attr("name"));
		} else {
            console.log("there is some error!");
			return;
		}
}

I was basically trying to have a form where user can either approve or disapprove/ reject a product for further processes in a task. My HTML form is something like this -

<form method="POST" action="{% url 'tasks:review-task' taskid=product.task_id.id %}"
	class="review-form">
    {% csrf_token %}
	<input type="hidden" name="product_id" value="{{product.product_id}}" />
	<input type="hidden" name="task_id" value="{{product.task_id_id}}" />
	<button type="submit" name="approve_btn" class="btn btn-link" id="approve-btn">
		<i class="fa fa-check" style="color: rgb(63, 245, 63);"></i>
	</button>
	<button type="submit" name="reject_btn" class="btn btn-link" id="reject-btn">
			<i class="fa fa-times" style="color: red;"></i>
	</button>
</form>

Let me know if you have any doubts.

Solution 16 - Jquery

Try this:

$(document).ready(function(){
    
    $('form[name="testform"]').submit( function(event){
      
        // This is the ID of the clicked button
        var clicked_button_id = event.originalEvent.submitter.id; 
        
    });
});

Solution 17 - Jquery

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

add hidden field

Solution 18 - Jquery

For me, the best solutions was this:

$(form).submit(function(e){

   // Get the button that was clicked		
   var submit = $(this.id).context.activeElement;

   // You can get its name like this
   alert(submit.name)
   
   // You can get its attributes like this too
   alert($(submit).attr('class'))

});

Solution 19 - Jquery

Working with https://stackoverflow.com/a/17805011/1094772">this excellent answer, you can check the active element (the button), append a hidden input to the form, and optionally remove it at the end of the submit handler.

$('form.form-js').submit(function(event){
	var frm = $(this);
	var btn = $(document.activeElement);
	if(
		btn.length &&
		frm.has(btn) &&
		btn.is('button[type="submit"], input[type="submit"], input[type="image"]') &&
		btn.is('[name]')
	){
		frm.append('<input type="hidden" id="form-js-temp" name="' + btn.attr('name') + '" value="' + btn.val() + '">');
	}
    
    // Handle the form submit here

    $('#form-js-temp').remove();
});

Side note: I personally add the class form-js on all forms that are submitted via JavaScript.

Solution 20 - Jquery

Similar to Stan answer but :

  • if you have more than one button, you have to get only the first button => [0]
  • if the form can be submitted with the enter key, you have to manage a default => myDefaultButtonId

$(document).on('submit', function(event) {
    event.preventDefault();
    var pressedButtonId = 
         typeof $(":input[type=submit]:focus")[0] === "undefined" ? 
         "myDefaultButtonId" :
         $(":input[type=submit]:focus")[0].id;
    ...
 }

Solution 21 - Jquery

This is the solution used by me and work very well:

// prevent enter key on some elements to prevent to submit the form
function stopRKey(evt) {
  evt = (evt) ? evt : ((event) ? event : null);
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  var alloved_enter_on_type = ['textarea'];
  if ((evt.keyCode == 13) && ((node.id == "") || ($.inArray(node.type, alloved_enter_on_type) < 0))) {
    return false;
  }
}

$(document).ready(function() {
  document.onkeypress = stopRKey;
  // catch the id of submit button and store-it to the form
  $("form").each(function() {
    var that = $(this);

    // define context and reference
    /* for each of the submit-inputs - in each of the forms on
			 the page - assign click and keypress event */
    $("input:submit,button", that).bind("click keypress", function(e) {
      // store the id of the submit-input on it's enclosing form
      that.data("callerid", this.id);
    });
  });

  $("#form1").submit(function(e) {
    var origin_id = $(e.target).data("callerid");
    alert(origin_id);
    e.preventDefault();

  });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="form1" name="form1" action="" method="post">
  <input type="text" name="text1" />
  <input type="submit" id="button1" value="Submit1" name="button1" />
  <button type="submit" id="button2" name="button2">
    Submit2
  </button>
  <input type="submit" id="button3" value="Submit3" name="button3" />
</form>

Solution 22 - Jquery

This works for me to get the active button

            var val = document.activeElement.textContent;

Solution 23 - Jquery

It helped me https://stackoverflow.com/a/17805011/1029257

Form submited only after submit button was clicked.

var theBtn = $(':focus');
if(theBtn.is(':submit'))
{
  // ....
  return true;
}

return false;

Solution 24 - Jquery

I was able to use jQuery originalEvent.submitter on Chrome with an ASP.Net Core web app:

My .cshtml form:

<div class="form-group" id="buttons_grp">
    <button type="submit" name="submitButton" value="Approve" class="btn btn-success">Approve</button>
    <button type="submit" name="submitButton" value="Reject" class="btn btn-danger">Reject</button>
    <button type="submit" name="submitButton" value="Save" class="btn btn-primary">Save</button>
    ...

The jQuery submit handler:

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
    $(document).ready(function() {
    ...
    // Ensure that we log an explanatory comment if "Reject"
    $('#update_task_form').on('submit', function (e) {
        let text = e.originalEvent.submitter.textContent;
        if (text == "Reject") {
           // Do stuff...
        }
    });
    ...

The jQuery Microsoft bundled with my ASP.Net Core environment is v3.3.1.

Solution 25 - Jquery

I also made a solution, and it works quite well:
It uses jQuery and CSS


First, I made a quick CSS class, this can be embedded or in a seperate file.

<style type='text/css'>
    .Clicked {
        /*No Attributes*/
    }
</style>


Next, On the click event of a button within the form,add the CSS class to the button. If the button already has the CSS class, remove it. (We don't want two CSS classes [Just in case]).

    // Adds a CSS Class to the Button That Has Been Clicked.
    $("form :input[type='submit']").click(function () 
    {
        if ($(this).hasClass("Clicked"))
        {
            $(this).removeClass("Clicked");
        }
        $(this).addClass("Clicked");
    });


Now, test the button to see it has the CSS class, if the tested button doesn't have the CSS, then the other button will.

    // On Form Submit
    $("form").submit(function ()
    {
        // Test Which Button Has the Class
        if ($("input[name='name1']").hasClass("Clicked"))
        {
            // Button 'name1' has been clicked.
        }
        else
        {
           // Button 'name2' has been clicked.
        }
    });

Hope this helps! Cheers!

Solution 26 - Jquery

You can create input type="hidden" as holder for a button id information.

<input type="hidden" name="button" id="button">
<input type="submit" onClick="document.form_name.button.value = 1;" value="Do something" name="do_something">

In this case form passes value "1" (id of your button) on submit. This works if onClick occurs before submit (?), what I am not sure if it is always true.

Solution 27 - Jquery

A simple way to distinguish which <button> or <input type="button"...> is pressed, is by checking their 'id':

$("button").click(function() {
  var id = $(this).attr('id');
  ... 
});

Solution 28 - Jquery

Here is a sample, that uses this.form to get the correct form the submit is into, and data fields to store the last clicked/focused element. I also wrapped submit code inside a timeout to be sure click events happen before it is executed (some users reported in comments that on Chrome sometimes a click event is fired after a submit).

Works when navigating both with keys and with mouse/fingers without counting on browsers to send a click event on RETURN key (doesn't hurt though), I added an event handler for focus events for buttons and fields.

You might add buttons of type="submit" to the items that save themselves when clicked.

In the demo I set a red border to show the selected item and an alert that shows name and value/label.

Here is the FIDDLE

And here is the (same) code:

Javascript:

$("form").submit(function(e) {
  e.preventDefault();
  // Use this for rare/buggy cases when click event is sent after submit
  setTimeout(function() {

    var $this=$(this);
    var lastFocus = $this.data("lastFocus");
    var $defaultSubmit=null;

    if(lastFocus) $defaultSubmit=$(lastFocus);

    if(!$defaultSubmit || !$defaultSubmit.is("input[type=submit]")) {
      // If for some reason we don't have a submit, find one (the first)
      $defaultSubmit=$(this).find("input[type=submit]").first();
    }

    if($defaultSubmit) {
      var submitName=$defaultSubmit.attr("name");
      var submitLabel=$defaultSubmit.val();

       // Just a demo, set hilite and alert
      doSomethingWith($defaultSubmit);
      setTimeout(function() {alert("Submitted "+submitName+": '"+submitLabel+"'")},1000);
    } else {
      // There were no submit in the form
    }

  }.bind(this),0);

});

$("form input").focus(function() {
  $(this.form).data("lastFocus", this);
});
$("form input").click(function() {
  $(this.form).data("lastFocus", this);
});

// Just a demo, setting hilite
function doSomethingWith($aSelectedEl) {
  $aSelectedEl.css({"border":"4px solid red"});
  setTimeout(function() { $aSelectedEl.removeAttr("style"); },1000);
}

DUMMY HTML:

<form>
<input type="text" name="testtextortexttest" value="Whatever you write, sir."/>
<input type="text" name="moretesttextormoretexttest" value="Whatever you write, again, sir."/>

<input type="submit" name="test1" value="Action 1"/>
<input type="submit" name="test2" value="Action 2"/>
<input type="submit" name="test3" value="Action 3"/>
<input type="submit" name="test4" value="Action 4"/>
<input type="submit" name="test5" value="Action 5"/>
</form>

DUMB CSS:

input {display:block}

Solution 29 - 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 30 - Jquery

$('form').submit(function (ev) {
  let clickedButton = ev.originalEvent.explicitOriginalTarget;
});

Solution 31 - Jquery

Let's say I have these "submit" buttons:

<button type="submit" name="submitButton" id="update" value="UpdateRecord" class="btn btn-primary">Update Record</button>
<button type="submit" name="submitButton" id="review_info" value="ReviewInfo" class="btn btn-warning sme_only">Review Info</button>
<button type="submit" name="submitButton" id="need_more_info" value="NeedMoreInfo" class="btn btn-warning sme_only">Need More Info</button>

And this "submit" event handler:

 $('#my_form').on('submit', function (e) {
     let x1 = $(this).find("input[type=submit]:focus");
     let x2 = e.originalEvent.submitter.textContent;

Either expression works. If I click the first button, both "x1" and "x2" return Update Record.

Solution 32 - Jquery

You want to use window.event.srcElement.id like this:

function clickTheButton() {

var Sender = window.event.srcElement;
alert("the item clicked was " + Sender.id)

}

for a button that looks like:

<input type="button" id="myButton" onclick="clickTheButton();" value="Click Me"/>

you will get an alert that reads: "the item clicked was myButton.

In your improved example you can add window.event.srcElement to process_form_submission and you will have a reference to whichever element invoked the process.

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
QuestionhawkexpView Question on Stackoverflow
Solution 1 - JqueryhunterView Answer on Stackoverflow
Solution 2 - JqueryStanView Answer on Stackoverflow
Solution 3 - JqueryseddonymView Answer on Stackoverflow
Solution 4 - JqueryNick FView Answer on Stackoverflow
Solution 5 - JqueryJonathan CamenischView Answer on Stackoverflow
Solution 6 - JqueryKARView Answer on Stackoverflow
Solution 7 - JquerylawnbowlerView Answer on Stackoverflow
Solution 8 - JqueryThomas WilliamsView Answer on Stackoverflow
Solution 9 - JquerywmacView Answer on Stackoverflow
Solution 10 - JqueryandrewmoView Answer on Stackoverflow
Solution 11 - JquerySaheb MondalView Answer on Stackoverflow
Solution 12 - JqueryRoldanView Answer on Stackoverflow
Solution 13 - Jqueryjcane86View Answer on Stackoverflow
Solution 14 - Jqueryuser3074069View Answer on Stackoverflow
Solution 15 - JqueryKarishma SukhwaniView Answer on Stackoverflow
Solution 16 - JqueryGreesoView Answer on Stackoverflow
Solution 17 - JqueryanydasaView Answer on Stackoverflow
Solution 18 - JqueryJeramiah HarlandView Answer on Stackoverflow
Solution 19 - Jqueryrybo111View Answer on Stackoverflow
Solution 20 - Jqueryyann-hView Answer on Stackoverflow
Solution 21 - JqueryvasilenicusorView Answer on Stackoverflow
Solution 22 - JqueryMariana NagyView Answer on Stackoverflow
Solution 23 - Jqueryw4ksklView Answer on Stackoverflow
Solution 24 - Jquerypaulsm4View Answer on Stackoverflow
Solution 25 - JqueryJason CidrasView Answer on Stackoverflow
Solution 26 - JquerydarekkView Answer on Stackoverflow
Solution 27 - JqueryApostolosView Answer on Stackoverflow
Solution 28 - JqueryFrancescoMMView Answer on Stackoverflow
Solution 29 - JqueryBabiBNView Answer on Stackoverflow
Solution 30 - JqueryAlexandre PauloView Answer on Stackoverflow
Solution 31 - Jquerypaulsm4View Answer on Stackoverflow
Solution 32 - JqueryCos CallisView Answer on Stackoverflow