views:

129

answers:

4

I have a function that I'm using to prevent multiple postbacks of a form:

var submitted = false;
$(function() {
    $('form').bind('submit', function(e) {
        if (!submitted && CanSubmit(e)) {
            submitted = true;
            return true;
        } else {
            return false;
        }
    });
});

In the CanSubmit method, I need to interrogate the button that was clicked to determine whether I should allow the submit or not.

Note that I can't bind to specific click events - see this previous question for more details.

In Firefox, I can use e.originalEvent.explicitOriginalTarget, but this is apparently not available in IE.

How can I get this value from the e parameter in a cross-browser way?

+2  A: 

Use e.target - jQuery normalizes it for cross browser consistency.

The closest thing I could find for explicitOriginalTarget was document.activeElement (for IE) - it is the element that had focus during the event. There is no equivalent for webkit based browsers. So no, there is no real cross browser way to do this with only the event object.

CD Sanchez
In a `submit()` handler, `e.target` will refer to the `<form>` even when you click a submit button. Here's an example: http://jsfiddle.net/zHbrC/
patrick dw
@patrick dw: Thank you, I was just testing that. I guess the event isn't actually fired from a submit button.
CD Sanchez
+2  A: 

Actually you could just replace $('form').bind('submit' with $(':submit').bind('click' and your code would work just as well (and you could use this to see what was clicked).

Tgr
The question states: *"Note that I can't bind to specific click events"*
patrick dw
That's correct - binding to the button assumes that it's only buttons that are causing form submits
Damovisa
@Damovisa, yes, and it is a correct assumption. Only submit buttons can cause a form to submit (or javascript submit() calls, but you presumably have those under control). The correct selector for them is `:submit`, not `:button`, though - I fixed that.
Tgr
That's the problem, unfortunately - I don't have control over all the submit functions. It's ASP.Net for a start, and there are elements on the page that can trigger a submit using javascript I don't easily have access to.
Damovisa
@Damovisa: in that case, use click handlers to save the click target (`$(':submit').click(function(){$(this).closest('form').data('source',this);});` or something to that effect).
Tgr
What happens if the uses hits `Enter` to submit the form? - There are multiple ways to submit a form. This is why the `submit` event is so useful.
Peter Ajtai
@Peter Ajtai: hitting Enter will cause a click event on the first input[type=submit] element of the form.
Tgr
@Tgr - Thanks. I hadn't realized that.
Peter Ajtai
+2  A: 

Why don't you unbind the submit function when you do a submit? This will guarantees only one submission:

$(function() {
    $('form').bind('submit', function(event) {
          // regular submit form stuff here
        ...
          // and unbind it
        $('this').unbind(event);       
    });
});

Checkout .unbind() under, "Using the event object"

Or, as Matt Ball pointed out in the comments, you can use .one(), which is equivalent to the above.

$(function() {
    $('form').one('submit', function(event) {           // <== Only executed once
          // regular submit form stuff here
        ...
    });
});

If you have the $.post() or $.get() submission of the form bound to multiple events / elements, then you simply have to make sure to unbind the handler that ends up being used from within itself using the event object, and then unbind all the other handlers too, and vice versa for each of these other handlers. You can unbind the other handlers using one of about four methods to unbind event handlers.

Peter Ajtai
A better way to guarantee a single event handler execution: [`jQuery.one()`](http://api.jquery.com/one).
Matt Ball
@Matt - Nice suggestion. Not sure how it's better though, they're equivalent according to the `.one()` documentation.
Peter Ajtai
Sure, they're equivalent, by why not use the purpose-built method? It's clearer (IMO) and more succinct. Anyway, I wasn't looking to get into a debate about it - just the usual "use what's already been created."
Matt Ball
@Matt - You're right; saving a few keytrokes is always a good thing ;) ---- Just wanted to point out that they actually do the exact same thing. - edited `.one()` into the answer.
Peter Ajtai
A: 

Why not use the .one function, guarantees it fires only once.

$(function() {
    $('form').one('submit', function(event) {
      // regular submit form stuff here     
    });
});
Randall Kwiatkowski
Hmm, a nice idea, but I think this might be the opposite of what I need - the form will submit unless I stop it, so I'd need to run the function every time *except* the first time.
Damovisa