0

I'm having some real trouble trying to get this form to work properly. The form should validate each field and successfully charge a credit card before submitting.

The issue is that I can't pass my return value to the parent function to prevent the form from submitting. I read this post and tried using deferred objects, a callback function, and placing return statements all over the place but I'm missing something. I've been at this for about a week and the frustration is getting to me. Could anyone help me with this? I would greatly appreciate it and thanks!

HTML:

<form onSubmit="return billingfunction1();" name="form5" method="post" action="" id="newform">
    </form>

JS: (trimmed to size)

function billingfunction1() {
var first_name = $.trim($("#first_name").val());
var last_name = $.trim($("#last_name").val());
var cardtype = $.trim($("#cardtype").val());

var maxlen = 16;


var digits = cardnumber.toString().length;
var submiteval;


if (cardtype == '') {
   // alert("Enter Card Type");
    $('#cardtype_msg').html('Enter Card Type.');
   $('#cardtype').css('border','1px solid #28a616');
   $('#cardtype').css('box-shadow','0 0 3px 0 #28a616');
    return false;
} else if (nameoncardfirst == '') {
    //alert("Enter Name On Card");
     $('#nameoncardfirst_msg').html('Enter First Name On Card.');
   $('#nameoncardfirst').css('border','1px solid #28a616');
   $('#nameoncardfirst').css('box-shadow','0 0 3px 0 #28a616');
    return false;
} else if (nameoncardlast == '') {
    //alert("Enter Name On Card");
     $('#nameoncardlast_msg').html('Enter Last Name On Card.');
   $('#nameoncardlast').css('border','1px solid #28a616');
   $('#nameoncardlast').css('box-shadow','0 0 3px 0 #28a616');
    return false;
} else {    
     function foo(callback) {
        return $.ajax({
        url: 'edit_billing2.php',
        data: "nameoncardfirst=" + nameoncardfirst+ "&nameoncardlast=" + nameoncardlast + "&street_address2=" + street_address2 +"&city2=" + city2 +"&state=" + state +"&zip=" + zip + "&cardnumber=" + cardnumber + "&expirationdate=" + expirationdate + "&cvv=" + cvv + "&cardtype=" + cardtype+ "&amount=" + amount + "&gender=" + gender + "&first_name=" + first_name + "&last_name=" + last_name + "&address=" + address + "&address2=" + address2 + "&city=" + city + "&post_code=" + post_code + "&country=" + country + "&mobile=" + mobile + "&email=" + email + "&newsletter=" + newsletter + "&make=" + vehicle + "&model=" + model + "&model_year=" + model_year,

        success: callback                
        });
    }
    function myCallback(response) {
        console.log("Success response. Attempting to authorize payment.");
            //alert(response);
            result = response.split('_');
            //alert("Successfully Saved");
            alert(result[0]);
           if(result[0]=="Your Payment has completed successfully")
           {
            console.log("Payment Success");

            submiteval = true;   
           }
           else
           { 
            console.log("Payment Failed, Aborting form submission.");
            submiteval = false;
           }
            return submiteval;
    }
    console.log("Valid inputs: attempting to pass via AJAX");
    foo(myCallback).done(function(response) {
        return submiteval;
    });
}

EDIT:

I tried using event.preventDefault() to stop the submission and handle the submission manually, but then the form would reload the current page and skip over some PHP I had before the form code that I neglected to mention:

if  (isset($_POST[Submit]))
{
//    do registration things
}

I ended up changing the $_POST[Submit] to

if  ($_SERVER['REQUEST_METHOD'] == 'POST')
{ 
//    do registration things
}

removing the onsubmit attribute from my form:

<form name="form5" method="post" action="" id="newform">

and moving it to my submit button:

<input onClick="return billingfunction1();" type="submit" value="Submit" 
name="Submit" class="submit_btn">

My new callback function will submit the form manually under the success condition:

function myCallback(response) {
    console.log("Success response. Attempting to authorize payment.");
    result = response.split('_');
    alert(result[0]);
    if(result[0]=="Your Payment has completed successfully") {
           console.log("Payment Success");
           document.forms["form5"].submit();
    } else { 
        console.log("Payment Failed, Aborting form submission.");
    }
}

Everything seems to be working as it should. Thanks so much for your help!

DH3
  • 1
  • 1
  • 2
    Nothing can help you here. The decision about whether or not to cancel the default action has to be made *synchronously*. Callbacks, promises, etc make dealing with async code easier, but it doesn't make it synchronous. The typical solution in this case is to always cancel the default action and retrigger the event if necessary after the async code did its check. Lots of related questions / potential duplicates: https://stackoverflow.com/search?q=%5Bjavascript%5D+prevent+submit+ajax – Felix Kling May 09 '17 at 01:15
  • I see. I was thinking along those lines but the only solution I came across was to use async: false, but it seems to be against best practices. Cancelling and retriggering was the way to go, thanks! – DH3 May 09 '17 at 17:23

3 Answers3

0

You can just add a submit listener to the form

$("#newform").submit(function(){...})

Prevent the default action

event.preventDefault()

And submit the form manually

$("#newform").submit()

if the condition is meet when the response to the AJAX call comes back.

Titus
  • 22,031
  • 1
  • 23
  • 33
0

emphasized text

function billingfunction1() {
var first_name = $.trim($("#first_name").val());
var last_name = $.trim($("#last_name").val());
var cardtype = $.trim($("#cardtype").val());

var maxlen = 16;


var digits = cardnumber.toString().length;
var submiteval;


if (cardtype == '') {
   // alert("Enter Card Type");
    $('#cardtype_msg').html('Enter Card Type.');
   $('#cardtype').css('border','1px solid #28a616');
   $('#cardtype').css('box-shadow','0 0 3px 0 #28a616');
    return false; //show error to the user instead of returning false
} else if (nameoncardfirst == '') {
    //alert("Enter Name On Card");
     $('#nameoncardfirst_msg').html('Enter First Name On Card.');
   $('#nameoncardfirst').css('border','1px solid #28a616');
   $('#nameoncardfirst').css('box-shadow','0 0 3px 0 #28a616');
    return false; //show error to the user instead of returning false
} else if (nameoncardlast == '') {
    //alert("Enter Name On Card");
     $('#nameoncardlast_msg').html('Enter Last Name On Card.');
   $('#nameoncardlast').css('border','1px solid #28a616');
   $('#nameoncardlast').css('box-shadow','0 0 3px 0 #28a616');
    return false; //show error to the user instead of returning false
} else {    
        $.ajax({
        url: 'edit_billing2.php',
        data: "nameoncardfirst=" + nameoncardfirst+ "&nameoncardlast=" + nameoncardlast + "&street_address2=" + street_address2 +"&city2=" + city2 +"&state=" + state +"&zip=" + zip + "&cardnumber=" + cardnumber + "&expirationdate=" + expirationdate + "&cvv=" + cvv + "&cardtype=" + cardtype+ "&amount=" + amount + "&gender=" + gender + "&first_name=" + first_name + "&last_name=" + last_name + "&address=" + address + "&address2=" + address2 + "&city=" + city + "&post_code=" + post_code + "&country=" + country + "&mobile=" + mobile + "&email=" + email + "&newsletter=" + newsletter + "&make=" + vehicle + "&model=" + model + "&model_year=" + model_year,

        success: myCallback                
        });
    function myCallback(response) {
        console.log("Success response. Attempting to authorize payment.");
            //alert(response);
            result = response.split('_');
            //alert("Successfully Saved");
            alert(result[0]);
           if(result[0]=="Your Payment has completed successfully")
           {
            console.log("Payment Success");

            submiteval = true; 
            document.forms["form5"].submit();
           }
           else
           { 
            console.log("Payment Failed, Aborting form submission.");
            submiteval = false; //show error to the user instead of returning false
           }
            return submiteval;
    }
}
<form  name="form5" method="post" action="" id="newform">
<input type="button" value ="submit" onClick="billingfunction1();" />
    </form>

Assign billingfunction1 to onclick event instead of submit. use document.forms["form5"].submit() to manually submit the form after validating the response from server.

Chand Ra
  • 69
  • 6
-1

$.ajax has a option named beforeSend(func). U can validate ur data in this func, and return false to cancel ajax.