I am back on a project I last worked on 9 months ago, looking at some code we wrote and hoping there is now a better way to do this...
Though initially very impressed with jQuery's unobtrusive validation, we ended up having to put together the hack below (partly based on a blog post I can't put my hands on right now) to deal with remote validation. The problem being that where the server-side validation process was slow - typically anything involving a DB call - the validator would not wait for the response from the validation method and would act as though it had passed back a positive.
The hack is to basically keep checking if the validator has any pending requests and not carry on until it has none, when you can be sure of a true validation result:
function SaveChangePassword() {
// Find form, fire validation
var $form = $("#btnSave").closest("form");
if ($form.valid()) {
//Do nothing - just firing validation
}
// Calls method every 30 milliseconds until remote validation is complete
var interval = setInterval(saveWhenValidationComplete, 30);
// Check if validation pending, save and clear interval if not
function saveWhenValidationComplete() {
// Find form validator, check if validation pending - save once remote validation is finished
var validator = $form.data("validator");
if (validator.pendingRequest === 0) {
clearInterval(interval);
//Force validation to present to user (this will not retrigger remote validation)
if ($form.valid()) {
var closeButton = "<br/><input type='button' value='OK' style='font-size:small; font-weight:bold; float:right;' onclick=\"$('#changePasswordDialog').dialog('close');\" class='greenbutton' />";
// If form is valid then submit
$.ajax(
{
type: "POST",
url: "/Account/SavePassword",
data: $form.serialize(),
success: function (result) {
var successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
$("#changePasswordDialog").html(successMessage + closeButton);
},
error: function (jqXhr, textStatus, errorThrown) {
// Populate dialog with error message and button
var errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
$("#changePasswordDialog").html(errorMessage + closeButton);
}
});
}
// Else validation will show
}
// Else don't save yet, wait another 30 miliseconds while validation runs
};
// Prevent default and stop event propagation
return false;
}
I am hoping that in the last 9 months there have been some developments and this is no longer necessary! Any ideas welcome, let me know if i can provide any further detail.