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

Viewed 99518

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.

22 Answers

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

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

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.

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.

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

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

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 detail in this answer here: (https://stackoverflow.com/a/66334184/11320178)
Let me know if you have any doubts.

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>

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

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.

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

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

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

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

Without jquery

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

I was finally able to find a complete and easy answer to the question : How can I get the button that caused the submit from the form submit event ?

I'll give you a simple example :

CODE HTML : The form

<form id="myForm" enctype="multipart/form-data" method="post">

  ...
  all input, select, textarea ...
  ....

  <button id="bt1" value="add" type="submit">Add</button>
  <button id="bt2" value="back" type="submit">Back</button>
  <button id="bt3" value="remove" type="submit">Remove</button>
  <button id="bt4" value="register" type="submit">Register</button>
</form>

CODE JAVASCRIPT : event listener and actions

var myFctSubmit = function(event){
   var myTarget = event.target || event.srcElement;
   var myButton = event.originalEvent.submitter;

   var balise_form = $(myTarget).attr('id');
   var balise_button = $(myButton).attr('id');

   //Now you know the button and
   //you can apply the script you want...
   //here in this exemple :
   //balise_form = myForm
   //balise_button = {button that you click}

}

$('#myForm').bind('submit',myFctSubmit);

Therefore, the solution to this problem is to fetch the following element :

event.originalEvent.submitter

Good luck everyone

Related