How to complete $.get() when a form is submitted using jQuery
I am using a third party shopping cart that sends a registration form to a .cgi script.
I want to send information from that form to me, and the customer via a jQuery $.get() function call.
The $.get calls a registration.mail.php script.
The problem is that the form submitting seems to cancel out the ajax call before the ajax call can be completed.
I can think of some inelegant solutions, and I have decided, because I'm about to travel, to use a counter and make the user click 'Register' twice. This solution hurts my soul obviously.
Here's the Javascript, that lives in the footer:
<script type="text/javascript">
var getsuccess = false;
$(document).ready(function() {
$('form#registerWholesale').bind('submit', function() {
$email = $('#email').val();
$username = $('#contactname').val();
$company = $('#company').val();
$phone = $('#billphone1').val();
$message = "A new customer has registered at the wholesale website. \n ";
$message += "They have the username of: " + $username + ". \n";
$messag开发者_运维技巧e += "Their company is: " + $company + ". \n";
$message += "Their email is: " + $email + ". \n";
$message += "Their phone is: " + $phone + ". \n";
$message += "Please help them ASAP. You can access the back end of the site at: http://location of website admin backend";
$.get('/mail.php', {from: 'orders@OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
getsuccess = true;
});
if (getsuccess) {
return true;
}else{
return false;
}
});
</script>
And here is the registration.mail.php code.
<?php
//Vendor email (to us)
$to = "ouremail@OurCompany.com";
$subject = "URGENT--New Registration--URGENT";
$message = htmlentities($_GET['message'], ENT_QUOTES, 'UTF-8');
//$message = $_GET['message'];
$from = htmlentities($_GET['from'], ENT_QUOTES, 'UTF-8');
//$from = trim($_GET['from']);
$headers = "From: $from";
mail($to,$subject,$message,$headers);
//echo "Mail Sent.";
//Customer email (to them)
$to_cust = htmlentities($_GET['email'], ENT_QUOTES, 'UTF-8');
$subject_cust = 'OurCompany Online Wholesale Account Request Recieved';
$message_cust = "Thank you for you interest in OurCompany's new wholesale website. \n\n
We have received your request to create an account. In order to obtain a wholesale account, a OurCompany representative must verify your account information and details by telephone. OurCompany will contact you within 1 business day at the telephone number that we have on file, or feel free to give us a call at 1-xxx-xxx-xxxx anytime if you would like a more rapid approval. \n\n
Thanks Again ~ OurCompany";
$headers_cust = "From: orders@OurCompany.com";
mail($to_cust,$subject_cust,$message_cust,$headers_cust)
?>
Thank you!
Your Ajax get handler sets up an asynchronous callback. In other words, this piece of code:
$.get('/mail.php', {from: 'orders@OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
getsuccess = true; <---- THIS
});
The "THIS" line is only called when the Ajax call returns a result. Since you are sending an actual email, it may take a long time.
So, by the time you run this:
if (getsuccess) {
return true;
}else{
return false;
}
The Ajax call has never completed, and this always returns false.
You should basically just decide whether you want to submit the form with Ajax or not, and only use one of those. If you want to do Ajax, the Submit event handler should always return False.
EDIT: I did not realize that the mail sending and form submitting are two different actions, and two separate server calls. (You are not showing the rest of your app, but this is the idea that I get from other answers.) This is bad design that may lead to inconsistent results and bad data. You should redesign your app so that both of these things are handled on server side in the same place, so that the web app only makes one call, no matter if this one call is by Ajax or regular form submit.
One solution is to bind the event to the button click , prevent the default action of the click so the form does not submit, then finally submit the form in the .get callback.
N.B As Jaanus suggests you should really look at the app design and send the mail and save the cart in the same call. What happens if the email gets sent then the form submission action fails?
$(document).ready(function() {
$('#yourSubmitButton').click( function(ev) {
//prevent form submission
ev.preventDefault();
$email = $('#email').val();
$username = $('#contactname').val();
$company = $('#company').val();
$phone = $('#billphone1').val();
$message = "A new customer has registered at the wholesale website. \n ";
$message += "They have the username of: " + $username + ". \n";
$message += "Their company is: " + $company + ". \n";
$message += "Their email is: " + $email + ". \n";
$message += "Their phone is: " + $phone + ". \n";
$message += "Please help them ASAP. You can access the back end of the site at: http://location of website admin backend";
$.get('/mail.php', {from: 'orders@OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
//all is well, submit the form
$('#yourForm').submit()
});
});
At the very least, rather than make them click twice, why dont you make the success callback of the $.get submit the form again for them?
$('form#registerWholesale').bind('submit', function() {
if (getsuccess) {
return true;
} else {
$email = $('#email').val();
$username = $('#contactname').val();
$company = $('#company').val();
$phone = $('#billphone1').val();
$message = "A new customer has registered at the wholesale website. \n ";
$message += "They have the username of: " + $username + ". \n";
$message += "Their company is: " + $company + ". \n";
$message += "Their email is: " + $email + ". \n";
$message += "Their phone is: " + $phone + ". \n";
$message += "Please help them ASAP. You can access the back end of the site at: http://location of website admin backend";
$.get('/mail.php', {from: 'orders@OurCompany.com', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
getsuccess = true;
$('form#registerWholesale').submit();
});
return false;
}
});
Have you tried putting the ajax call in a function, and hooking the onSubmit of the form?
onsubmit="myajaxcallFunc(); return true;"
This is commonly used to stop the submission, with return false, but in this case it may do what you want.
The callback you're passing to $.get
will be evaluated after the AJAX request. Since AJAX is asynchronous, your code will continue to evaluate in the mean time, which means your if-condition with the two return-statements will always evaluate before the AJAX callback is called.
What you want to do is for the submit
listener to always return false, and in the AJAX callback, you conditionally trigger $('form#registerWholesale').submit();
Of course there's a design consideration here as well: you may want the e-mail sending and wholesale registration to be atomical. If the mail is sent, you always want the stuff that happens in form submit to happen as well, right? In that case you want to move either the email sending to the form postback, or the wholesale registration to the AJAX callback, so it's all handled in one step.
精彩评论