I'm running a validation on form data, such that when somebody hits the submit button it checks the form's contents first. A number of fields (could be zero, could be more than one, depending on the page) have things like unique codes which require checking with the server first. I'm running an asynchronous request to the server, which simply responds 'ok
' or 'taken
' for each field. If any of the fields have errors, the page doesn't submit.
On the one hand, this should be asynchronous: it should continue validating the rest of the form fields while that request is off processing, including firing off other requests. If the call is made synchronously, then it visibly slows down feedback on later fields.
On the other hand, I want to make sure all the validation requests have returned (or timed out) before responding yes or no to the validate()
method, and either allowing the submit to proceed or not. So if there are two fields that need validating then the validate()
method should fire off those two AJAX requests, process the rest of the fields, and then wait until those two requests have returned before finally returning.
I can probably achieve this with some ugly homebaked solution (probably involving an array of random ids representing the requests in progress or something), but before I do is there any built-in function, plugin or standard technique I should be using instead?
Clarification
What I think I need is to make the code wait for the result from one or more asynchronous requests before proceeding with a method. This isn't the same as a callback, because the result of the method depends on the result of the requests. It isn't the same as a synchronous request because there may be more than one of them.
I'm using this to check the form before submitting:
$("form").submit(function () {
return validate($(this));
});
If the validate()
method returns false, then the form doesn't submit. validate()
hilights any fields that aren't accepted. For normal fields, validate()
looks something like this (vastly simplified version, without the feedback):
function validate(form) {
resetWarnings(form);
var ok = true;
// required fields
form.find("input.required").each(function () {
var field = $(this);
if (field.val() === "") {
ok = false;
}
return this; // meaningless in this case but a good habit to keep
});
// fields that matches a pattern
form.find("input.pattern").each(function () {
var field = $(this);
var pattern = field.data("pattern");
if (!field.val().match(pattern)) {
ok = false;
}
return this;
});
// various other rules for other sorts of field
...
return ok;
}
For AJAX fields it's more like this:
form.find("input.lookup").each(function () {
var field = $(this);
var url = field.data("lookup");
$.ajax({
url: url,
data: { code: field.val() },
success: function (result) {
if (result === "taken") {
ok = false;
}
}
}
});
But of course, validate()
has already finished before the success method is called. So if I can make it wait until the ajax has been completed (either success or error) before returning, I can get the right result and stop the form being submitted. And if I made the ajax synchronous, then the entire method stops until it's done, which is wrong.
Further thought
Given Javascript's threading model (which is to say none at all), is what I'm asking for technically impossible?