jQuery binding ajaxStart and ajaxComplete to a form type?
my app has several jquery-ui-dialogs, all which do very different things. Here's the common template between them:
<div class="dialog-content">
<form accept-charset="UTF-8" action="/NOT-UNIQUE" class="NOT-UNIQUE" data-remote="true" id="NOT-UNIQUE" method="post">
<div class="ui-dialog-body">
all the fields
</div>
<div class="ui-dialog-footer">
<input class="button" id="NOT-UNIQUE" name="commit" type="submit" value="NOT-UNIQUE">
<input type="button" class="button" name="cancel" value="Cancel">
</div>
</form>
</div>
What I'd开发者_运维知识库 like to do is anytime a .dialog-content form is submitted, is disable the submit button so that users don't submit multiple times.
So far I have:
$(".dialog-content").live("submit",function(){
// Comment AJAX UI, spinner, disable - Needs to be inside the submit to work dynamically
$("form", this).ajaxStart(function() {
// Disable button
$("input[type=submit]", this).attr("disabled", true);
});
$("form", this).ajaxComplete(function() {
// Re-enable button
$("input[type=submit]", this).removeAttr("disabled");
});
});
But that doesn't seem to work. The goal is to not have to write this for every dialog but once that works for all dialogs.
Thoughts?
ajaxStart/Complete is a global event, so you can't tell which form it is for.
Is jQuery UI dialog doing the AJAX automatically or are you calling it somewhere else? If it is doing it automatically, have a look at the API... it probably fires a custom event on the form, say "formSubmitted", so bind to that instead:
$("form", this).bind("formSubmitted", function() {
// Re-enable button
$("input[type=submit]", this).removeAttr("disabled");
});
If you're calling the AJAX yourself, then just trigger "formSubmitted" on the form in the AJAX success handler.
Came across this today and wanted to share with anyone else looking.
While you can't call the unknown form, you can do as I did and create an "Ajax Wrapper". It has the advantage of condensing code, while not affecting capability. The disadvantage is a small amount of performance overhead.
Define all the defaults you want within the function. I like this because I use some near-global success/error handles for dialogs.
function ajaxWrapper(srcForm,overrides) {
var ret = $.extend(true,{type: "POST",
url: $(srcForm).attr('action'),
contentType: "application/x-www-form-urlencoded",
data: {
tzOffset: new Date().getTimezoneOffset(),
},
success: // success handler,
error: // error handler,
beforeSend: function(jqXhr,plainObject) {
$(srcForm).find("button[type=submit], button[type=reset], input[type=submit], input[type=reset]").prop("disabled", true);
},
complete: function(jqXHR, textStatus) {
$(srcForm).find("button[type=submit], button[type=reset], input[type=submit], input[type=reset]").prop("disabled", false);
}
},overrides);
$.ajax(ret);
}
It uses $.extend(true,,)
to merge the objects. True
sends it to a deep copy enabling both objects to have a data
object and inheriting properties from both, while overriding in favor of overrides
where the two object's data
might conflict.
If you don't want an override, remove true,
. False is not supported, as per the current docs.
I call the function like simple as this
ajaxWrapper($(this),{url: $(this).attr('action'), // I choose to leave action in just to make clear to me where this ajax is submitting
data: {ObjectID: $('#myID').val(),
f1: $('#f1').val(),
f2: $('#f2').val(),
someCheckbox: $('#someCheckbox').prop('checked')}
});
精彩评论