开发者

Determining which submit button was clicked from jQuery/JavaScript [duplicate]

This question already has answers here: How can I get the button that caused the submit from the form submit event? (22 answers) Closed 9 years ago.

I'm ajaxifying some forms from a PHP application I didn't write. To do this, I came up with this clever solution:

jQuery("form").submit(function(event) {
    // get some values from elements on the page:
    var the_form = jQuery(this);
    var data = the_form.serialize();
    var url = the_form.attr( 'action' );
    var button = event.originalEvent.explicitOriginalTarget;

    data = data + "&" + button.name + "=" + button.value;

    // Send the data using post and put the results in a div
    jQuery.post( url, data, function() {
        //Do something crazy
    });

    // stop form from submitting normally
    if (event.preventDefault) 
    { 
        event.preventDefault(); 
    } 
    else 
    {
        event.returnValue = f开发者_C百科alse; 
    }
});

Which works perfectly. I went away rejoicing. The problem is, I inadvertently used a Mozilla/Gecko only property to determine which button was clicked. (event.originalEvent.explicitOriginalTarget) Which means this only works in Firefox. :-(

All of this is necessary because the web app I'm augmenting relies on the button name/value being in the post data to process the form correctly. So, my question in simple terms would be:

What is the best, cross-browser way to determine which button was clicked in jQuery's submit event?

Edit: And here is my solution.

jQuery("some selector that targets your form").find(":submit").click(function(event) {
    // get some values from elements on the page:
    var the_form = jQuery(this).parents("form");
    var data = the_form.serialize();
    var url = the_form.attr( 'action' );
    var button = event.target;

    data = data + "&" + button.name + "=" + button.value;

    // Send the data using post and put the results in a div
    jQuery.post( url, data, function() {
        //Do something crazy
    });

    // stop form from submitting normally
    if (event.preventDefault) 
    { 
        event.preventDefault(); 
    } 
    else 
    {
        event.returnValue = false; 
    }
});


See this question: Crossbrowser equivalent of explicitOriginalTarget event parameter

You're going to have to attach the event listeners to the buttons instead of the form to get a good reliable way of determining which one fired the submit.


http://api.jquery.com/event.target/

jquery.event.target should work because it is normalised for most browsers.

jquery.event.currentTarget can be used to retrieve the current item in the event bubbling chain.

Edit-- After some reflection and @greg's suggestion: I've posted a code snippet on jsfiddle.


Using click handlers to submit the form is problematic beacuse you cannot use submit event handlers for validation (which is the way pretty much any validator plugin does it). Also, when you are not using AJAX to post, disabling submit buttons can have weird effects in some browsers if done in the click event and not the submit event.

The way jQuery.Form solves this is to set up a click handler which stores the clicked button (and then clears it with a small timeout), and use the submit handler to actually send the form contents via AJAX.


Here is a function I used to "ajaxify" my forms with jQuery.

function ajaxifyForm(form, callback)
{
    var clicked

    form.find("button").click(function()
    {
        if (clicked != null) clicked.removeAttr("data-clicked")
        clicked = $(this)
        $(this).attr("data-clicked", 1)
    })

    form.submit(function(event)
    {
        var data = {}
        var name = ""

        form.find(":input").each(function()
        {
            var input = $(this)

            if (!(name = input.attr("name"))) return

            switch (input.attr("type"))
            {
                case "radio":
                case "checkbox":
                    if (input.attr("checked")) data[name] = input.val()
                    break
                case "submit":
                    if (input.attr("data-clicked")) data[name] = input.val()
                    break
                default:
                    data[name] = input.val()
            }
        })

        $.ajax({
            url: form.attr("action"),
            success: function(data)
            {
                if (typeof callback == "function") callback("success")
            },
            error: function()
            {
                if (typeof callback == "function") callback("error")
            },
            data: data,
            type: form.attr("method")
        })

        return false
    })

    return form
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜