views:

45

answers:

5

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";
        $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: '[email protected]', 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 = "[email protected]";
$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: [email protected]";
mail($to_cust,$subject_cust,$message_cust,$headers_cust)
?> 

Thank you!

+1  A: 

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: '[email protected]', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {

           //all is well, submit the form
           $('#yourForm').submit()

       });

    });
redsquare
This is the exact solution I knew I was not reaching. Thank you. I wish I could redesign the app, but that's why I put in the first line, that it's a 'third party shopping cart'. I can't change the logic.
brennanag
@brennanag you could use a server side http post to avoid this. Good luck with it
redsquare
@redsquare can you explain what you mean a little more? I can't access the .cgi script inner workings if that affects anything.
brennanag
see http://davidwalsh.name/execute-http-post-php-curl for how to do a php httppost
redsquare
@redsquare great article. Thanks very much.
brennanag
A: 

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.

Fosco
I like redsquare's answer better... using type=button instead of type=submit and having the ajax callback do the submission.
Fosco
hey forso - the type is not important in my answer, it will prevent the submission if type is submit.
redsquare
+2  A: 

Your Ajax get handler sets up an asynchronous callback. In other words, this piece of code:

  $.get('/mail.php', {from: '[email protected]', 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.

Jaanus
+1 for the edit
redsquare
I am using a third party app. I can't redesign it.
brennanag
As others said, you could look into how to do posts from the server side into the 3rd party app, so that the client from browser would still make only one call.
Jaanus
A: 

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.

David Hedlund
+1  A: 

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: '[email protected]', message: $message, email: $email, username: $username, company: $company}, function(data, textStatus, xhr) {
         getsuccess = true;
         $('form#registerWholesale').submit();
      });
      return false;
    }
});
Jake
I moved the accepted result to this answer, because, well, it's the same as redsquare's, it was 1 minute sooner, and look at the reputation difference... nothing personal.
brennanag
@brennanag it was actually 1 minutes later and is not the same solution - the above still uses a variable which is not needed. I do not mind about the points but if anyone else views the question+ticked answer they may not get the best approach.
redsquare
@redsquare ah! you are right completely. I will move it back for clarity's sake, as that is more important in the end. Sorry Jake. :)
brennanag