Reputation: 137
I have a bit of a problem. When a form is submitted, I wan't to check some things about it, and if something is wrong, I want to prevent it from submitting and then show an error on the client side. Everything seems to work fine except the form keeps submitting. It even shows the error on client side for a split second before it submits.
$('#register').on('submit', function (e) {
e.preventDefault();
var username = $("#register-username"),
name = $("#register-name"),
email = $("#register-email"),
password = $("#register-password"),
confirmPassword = $("#register-confirmPassword");
checkUsername(function (res) {
if (res) {
checkEmail(function (res) {
if (res) {
this.submit();
} else {
clearErrors();
email.toggleClass('input-error');
}
});
} else {
clearErrors();
username.toggleClass('input-error');
}
});
});
function checkEmail(callback) {
$.get("/checkEmail/" + $('#register-email').val(), function (data) {
if ( data == undefined ) {
callback(true);
} else {
callback(false);
}
});
}
function checkUsername (callback) {
$.get("/checkUsername/" + $('#register-username').val(), function (data) {
if ( data == undefined ) {
callback(true);
} else {
callback(false);
}
});
}
function clearErrors () {
var arr = [
$("#register-username"),
$("#register-name"),
$("#register-email"),
$("#register-password"),
$("#register-confirmPassword")
];
arr.forEach(function(el) {
el.removeClass('input-error');
});
}
Update: Now I am just confusing myself. checkUsername() returns undefined from my server, I know for a fact, but somehow it is reaching the 'else' statement where checkUsername() is called. I've added the rest of my code. Should clear some confusion.
Upvotes: 0
Views: 94
Reputation: 137
So I built off of charlietfl's solution and assigned the native form to a variable, and then submitted it within an anon function.
$('#register').on('submit', function (e) {
e.preventDefault()
var username = $("#register-username"),
name = $("#register-name"),
email = $("#register-email"),
password = $("#register-password"),
confirmPassword = $("#register-confirmPassword"),
form = document.getElementById('register');
$.get("/checkUsername/" + username.val(), function (data) {
if (data) {
clearErrors();
username.toggleClass('input-error');
} else {
$.get("/checkEmail/" + email.val(), function (data) {
if ( data ) {
clearErrors();
email.toggleClass('input-error');
} else {
form.submit();
}
});
}
});
});
This works.
Upvotes: 0
Reputation: 649
You need to return false from validation to stop the current submitting event, and then manually send the post request on success from when the callbacks have successfully returned.
Since the callback is running after the validation has returned from the server then you can actually affect whether a request is made. Where as the other solutions involve trying to change how the original submit event occurs which is no longer in scope since you've already sent requests to the server at this point.
$('#register').on('submit', function (e) {
var username = $("#register-username"),
name = $("#register-name"),
email = $("#register-email"),
password = $("#register-password"),
confirmPassword = $("#register-confirmPassword");
checkUsername(function (res) {
if (res) {
checkEmail(function (res) {
if (res) {
$.post('{insert form action here}', $(this).serialize());
} else {
clearErrors();
email.toggleClass('input-error');
}
});
} else {
clearErrors();
username.toggleClass('input-error');
}
});
return false;
});
You'll have to replace the {insert form action here}
, and $(this).action
might work in it's place, but I'm not sure.
Upvotes: 0
Reputation: 171690
Assuming the problem is due to asynchronous code not shown, an effective way is to use preventDefault
for the jQuery submit handler and use native submit when all validation passes
Something like:
$('#register').on('submit', function (e) {
e.preventDefault();// prevent jQuery submit
// after all validation passes
this.submit();// submit native method won't trigger jQuery handler again
})
Upvotes: 1
Reputation: 4453
The call to preventDefault
is made from the anonymous callback function you're passing to checkUsername
. If the anonymous function is called asynchronously, then it's too late to cancel the event.
Upvotes: 5