May 29, 2011

jQuery $.post doesn't pass what button were pressed

Question by Cheburek

Recently I’ve stuck with a problem where $.post does not send information about button which were pressed.
I.e. we have a form with two buttons.

<form method="post"  action="/home/index">

  <input type='hidden' name='data1' value='value1' />

  <button name="button1" type="submit">First</button>
  <button name="button2" type="submit">Second</button>

</form>

$(document).ready(function() {
    $('#formId').submit(function () {
        var f = $(this);
        var action = f.attr("action");
        var serf = f.serialize();
        $.post(action, serf,
        //onreturn
          function (data) {
                //do something here on success
              },
              'json'
          );
        return false;
      });
});

Without ajax form is posted as following if user pressed First button: data1=value1&button1

But when I use $.post posted form does not contain any information about button: data1=value1

jQuery 1.6.1

The behavior depends on that which button were pressed.
Any help or workaround would be appriciate!

Answer by T.J. Crowder

Since you’re stopping the browser’s default behavior, which is what supplies the button value, you’ll have to capture what button was pressed, and add that information to the data you’re posting (your serf data). Probably the most reliable way would be to hook the click event on the buttons as well as the submit event of the form, and route them all to a central function that does the ajax submission with (or without) a button value (without in the case of a form submitted another way, rather than by pressing one of those buttons).

Something along these lines:

$(document).ready(function() {
    function submitTheForm(f, button) {
        var action = f.attr("action");
        var serf = f.serialize();
        if (button && button.name) {
            serf += "&" + encodeURIComponent(button.name);
            if (button.value) {
                serf += "=" + encodeURIComponent(button.value);
            }
        }
        $.post(action, serf,
        //onreturn
          function (data) {
                //do something here on success
          },
          'json'
        );
    }
    $('#formId').submit(function () {
        submitTheForm($(this));
        return false;
    });
    $("#formId :submit").click(function() {
        submitTheForm($(this).closest('form'), this);
        return false;
    });
});

Answer by Starx

I don’t think that is suppose to be happening. But anyways, you could something like this too.

$("#formid").children("input[type="submit"]").click(function() {
    var name = $(this).attr("name");
    post(name);
    return false;
});
function post(buttnname) {
    var action = $("#formid").attr("action");
    var serf = $("#formid").serialize()+"&button="+buttname;
    $.post(action, serf,
    //onreturn
        function (data) {
            //do something here on success
          },
          'json'
        );
}
...

Please fill the form - I will response as fast as I can!