How can I correctly capture and re-fire the form submit event, guaranteed?
These two functions might help you bind event handlers at the front of the jquery queue. You'll still need to strip inline event handlers (onclick
, onsubmit
) and re-bind them using jQuery.
// prepends an event handler to the callback queue
$.fn.bindBefore = function(type, fn) {
type = type.split(/\s+/);
this.each(function() {
var len = type.length;
while( len-- ) {
$(this).bind(type[len], fn);
var evt = $.data(this, 'events')[type[len]];
evt.splice(0, 0, evt.pop());
}
});
};
// prepends an event handler to the callback queue
// self-destructs after it's called the first time (see jQuery's .one())
$.fn.oneBefore = function(type, fn) {
type = type.split(/\s+/);
this.each(function() {
var len = type.length;
while( len-- ) {
$(this).one(type[len], fn);
var evt = $.data(this, 'events')[type[len]];
evt.splice(0, 0, evt.pop());
}
});
};
Bind the submit handler that performs the ajax call:
$form.bindBefore('submit', function(event) {
if (!$form.hasClass('allow-submit')) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
// perform your ajax call to validate/whatever
var deferred = $.ajax(...);
deferred.done(function() {
$form.addClass('allow-submit');
});
return false;
} else {
// the submit event will proceed normally
}
});
Bind a separate handler to block click events on [type="submit"]
until you're ready:
$form.find('[type="submit"]').bindBefore('click', function(event) {
if (!$form.hasClass('allow-submit')) {
// block all handlers in this queue
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
return false;
} else {
// the click event will proceed normally
}
});
Bind to the form's submit handler with jQuery and prevent the default action, then, when you want to submit the form, trigger it directly on the form node.
$("#formid").submit(function(e){
// prevent submit
e.preventDefault();
// validate and do whatever else
// ...
// Now when you want to submit the form and bypass the jQuery-bound event, use
$("#formid")[0].submit();
// or this.submit(); if `this` is the form node.
});
By calling the submit
method of the form node, the browser does the form submit without triggering jQuery's submit handler.