Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: Find clicked element when binding to a form submission event?

I think this should be simple. Say I've got the following jQuery:

$someForm.live('submit', function(event) {
// do something
});

If there is more than one submit button (<button type="submit">) in that form, and I want to refer to the name attribute of the button that was clicked, how would I do that within the callback function?

Update - Clarification

In the callback context, both this and event.target refer to the form itself, and event is a deeply nested object. It may contain what I'm looking for, but I haven't found it yet.

Another way to phrase this question would be, "if I'm watching for a submit event on a form (not its child elements), is there any way, when I handle that event, to determine the child element from which the event bubbled up to the form?" Is the clicked element even available at that point, or does the browser just consider it an event on the form itself that had no deeper origin?

Update 2 - Answer

It appears that the answer is what Nick Craver said - that the submit event originates at the form itself, so it can't be traced back to the button, which had a click event, not a submit event. In order to get any further information from the click, it's necessary to have a click listener for the button.

In some cases (like mine), you may need both 1) to capture which submit button is clicked and 2) to bind to the submit event on the form. For example, if you're using jQuery Validate, it prevents the form from submitting until it's valid. If you make the form submit via ajax by binding to the button click, you'll bypass that validation.

As Nick showed, you can solve this by capturing the button info using a click listener for the buttons, and then use this information in the form's submission callback.

A clean way to pass the button's info from the click callback to the form's submission callback is to use jQuery.data() to store the it on the form. For example:

// In the button's click event callback...
jQuery.data($someForm, 'lastSubmitButton', event.target.name);

// In the form's submit event callback...
var whichButton = jQuery.data($someForm, 'lastSubmitButton');

This prevents the need for a global variable.

like image 374
Nathan Long Avatar asked Dec 13 '10 14:12

Nathan Long


2 Answers

Normally you can use event.target for the element itself...and in this case, since it's a native DOM property, just use .name as well:

$someForm.live('submit', function(event) {
  var name = event.target.name;
});

However, since submit doesn't originate from the button, only a click does, you want something more like this:

$("form :submit").live('click', function(event) {
  var name = this.name;
});

Use this here, because as @patrick points out, a <button> can have children as well, and the target may be a child in those cases.

like image 107
Nick Craver Avatar answered Oct 30 '22 18:10

Nick Craver


You can use the target property of the event object to get the element that initiated the event:

$(":submit").click(function(event) {
    var initiatingElement = event.target;
    // Do something with `initiatingElement`...
});

EDIT: Note that, for that to work, you will have to handle the click events of your submit buttons instead of the submit event of your form.

like image 21
Frédéric Hamidi Avatar answered Oct 30 '22 18:10

Frédéric Hamidi