0

I have a formA that posts and saves to the MYSQL DB

<form name="A" id="FormA" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">  <== first visable form ,Submitting the data into DB
    ........field inputs. ..... 
    <input type="submit" class="btn btn-primary" value="Submit">
</form>

I have a hidden form called PayForm that store some var with hidden input method and get the $input_amount as amount from FromA

It is noted that I haven't made the submit button .

This form is going to post to the EPayment Gateway .

<form name="payForm" id="payForm" method="post" action=" https://test.paydollar.com/b2cDemo/eng/payment/payForm.jsp">
    <input type="hidden" id="merchantId" value="sth">
    <input type="hidden" id="amount" value="<?php echo $input_amount; ?>" >
    <input type="hidden" id="orderRef" value="<?php  date_default_timezone_set("Asia/Taipei");  $date = date('m/d/Y h:i:s a', time()); echo $date ; ?>">
    <input type="hidden" id="currCode" value="sth" >
    <input type="hidden" id="mpsMode" value="sth" >
    <input type="hidden" id="successUrl" value="http://www.yourdomain.com/Success.html">
    <input type="hidden" id="failUrl" value="http://www.yourdomain.com/Fail.html">
    <input type="hidden" id="cancelUrl" value="http://www.yourdomain.com/Cancel.html">
    ...
</form>

Here is my idea workflow :

1)User press "Submit" button in FormA ==> info in FormA is going to store into DB .

2)JS is running . Force the PayForm to post automatically . Then, The user is directed to the Payment Gateway .

In short , the Submit button in FormA trigger both forms post actions .

Here is my JS

  <script type='text/javascript'>
   var payFormDone = false;
    $('#FormA').on('submit', function(e){
        if( !payFormDone ) {
            e.preventDefault(); // THIS WILL TRIGGER THE NEXT CODE
            $('#payForm').submit();

        }
    });

    $("#payForm").submit(function(event) {
        /* stop form from submitting normally */
       //event.preventDefault();

        /* get the action attribute from the <form action=""> element */
        var $form = $(this),
        url = $form.attr( 'action' );

        /* Send the data using post with element id name and name2*/
        var posting = $.post( url, { 
                merchantId: $('#merchantId').val(), 
                amount: $('#amount').val(), 
                orderRef: $('#orderRef').val(), 
                currCode: $('#currCode').val(), 
                mpsMode: $('#mpsMode').val(), 
                successUrl: $('#successUrl').val(), 
                failUrl: $('#failUrl').val(), 
                cancelUrl: $('#cancelUrl').val(), 
                payType: $('#payType').val(), 
                lang: $('#lang').val(), 
                payMethod: $('#payMethod').val(), 
                secureHash: $('#secureHash').val()
        } );

        /* Alerts the results */
        posting.done(function( data ) {
            alert('success'); 
         payFormDone = true;
            $('#FormA').submit();

        });
    });
    </script>

Now ,the idea is not working . It can only trigger second form action . The first form action is not triggered .At least ,the data in FormA has not saved to the DB .

In short ,

 posting.done(function( data ) {
        alert('success');
        payFormDone = true;
        $('#payFormCcard').submit();
    });

Is not working .I think !

update

This is how I post FormA to the server

<?php
// Include config file
require_once 'database.php';
header("Content-Type:text/html; charset=big5");
print_r($_POST);

// Define variables and initialize with empty values
$CName = $Address = $Phone = $amount= $Purpose= $Ticket = "";
$CName_err = $Address_err = $Phone_err = $amount_err = $Purpose_err = $Ticket_err="";

// Processing form data when form is submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Validate name
    $input_CName = trim($_POST["CName"]);
    if (empty($input_CName)) {
        $CName_err = "Please enter a name.";
    } elseif (!filter_var(trim($_POST["CName"]), FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => "/^[a-zA-Z'-.\s ]+$/")))) {
        $CName_err = 'Please enter a valid name.';
    } else {
        $CName = $input_CName;
    }
......
if (empty($CName_err) && empty($Address_err) && empty($amount_err) && empty($Phone_err)) {
        // Prepare an insert statement
        $pdo = Database::connect();
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $sql = "INSERT INTO donation (CName, Address, Phone, Amount ,Ticket, Purpose) VALUES (?, ?, ?, ? ,?, ?)";

        $q = $pdo->prepare($sql);
        $q->execute(array($CName, $Address, $Phone, $amount ,$Ticket ,$Purpose));
        Database::disconnect();

}

}
?>
evabb
  • 405
  • 3
  • 21
  • I don't see any code which stores FormA input fields data into the DB ... not sure even how many they are as you marked them as `........field inputs. .....` – Reflective Jun 28 '18 at 09:43
  • @Reflective around 10 fields are waiting to post – evabb Jun 28 '18 at 09:53
  • Where is the code which posts them to backend to store in the server? only a code which posts the fields in payForm is available. – Reflective Jun 28 '18 at 09:57
  • @Reflective Please see edited – evabb Jun 28 '18 at 09:59
  • `1)User press "Submit" button in FormA ==> info in FormA is going to store into DB .` The form is not submitted if `!payFormDone` as `e.preventDefault()` is preventing it. – Reflective Jun 28 '18 at 10:07
  • @Reflective the logic is that : Use `e.preventDefault() ` to stop the normal format submit (prevent page loading ) .Use ajax posting method to post hidden form and default form posting to post FormA – evabb Jun 28 '18 at 10:12
  • @Reflective If I don't use `e.preventDefault() ` ,the page loading and stop posting of second form – evabb Jun 28 '18 at 10:13
  • it's true, but if you want to first save FormA and then payForm in case `!payFormDone`, you should first submit FormA by a `$.post` and then in success handler of this request you should execute `$("#payForm").submit();` – Reflective Jun 28 '18 at 10:17
  • @Reflective Bro , would you mind build a sample code to let me reference from this – evabb Jun 28 '18 at 10:28

4 Answers4

0

you should not comment event.preventDefault(); from the second form. Currently what happens is it submitting it as default action which is post to url.

Manoz
  • 6,507
  • 13
  • 68
  • 114
0

The submit handler for FormA actually prevents the submission of the form. That's why data is not saved to db.

$('#FormA').on('submit', function(e){
    if( !payFormDone ) {
        e.preventDefault(); // => HERE you are preventing the form from submitting
        $('#payForm').submit();
    }
});

Here you are in the submit handler for the form, but the call to preventDefault stops the submit for FormA and instead triggers the submit of payForm. See https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault

Also instead of having that you trigger via javascript I'd probably send the first one normally. Then as response of the POST in the first form You might print a message to the user with something like: "You are being redirected to the payment gateway.. " and an hidden form with all the fields that is triggered automatically after x seconds. IMHO this approach is easier and more reliable.

So in the first html page I'll remove all your javascript code and leave only:

<form name="A" id="FormA" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
  ........field inputs. ..... 
  <input type="submit" class="btn btn-primary" value="Submit">
</form>

When the user clicks on the button he submits the data to the php page in POST. On the server the data is saved to DB and the server prints a message to the user and redirect to the payment gateway (via javascript this time). Something like:

<?php if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  .... save data to db
?>
<form name="payForm" id="payForm" method="post" action=" https://test.paydollar.com/b2cDemo/eng/payment/payForm.jsp">
  <input type="hidden" id="merchantId" value="sth">
  <input type="hidden" id="amount" value="<?php echo $input_amount; ?>" >
  <input type="hidden" id="orderRef" value="<?php  date_default_timezone_set("Asia/Taipei");  $date = date('m/d/Y h:i:s a', time()); echo $date ; ?>">
  <input type="hidden" id="currCode" value="sth" >
  <input type="hidden" id="mpsMode" value="sth" >
  <input type="hidden" id="successUrl" value="http://www.yourdomain.com/Success.html">
  <input type="hidden" id="failUrl" value="http://www.yourdomain.com/Fail.html">
  <input type="hidden" id="cancelUrl" value="http://www.yourdomain.com/Cancel.html">
  <p>You are being redirected to the payment gateway. If the redirect takes too long</p>
  <input type="submit" value"click here">
</form>
<script>
// submits the form after 5 seconds
setTimeout(function(){ $('#payForm').submit(); }, 5000);
</script>
<?php } // this ends the POST block ?>
filippo
  • 2,967
  • 1
  • 19
  • 19
  • You mean send the form automatically after X second with JS? – evabb Jun 28 '18 at 08:54
  • Yes I mean you put the form hidden in html and then you submit it via js after 5-10 seconds with a button to be clicked by the in case the automatic redirect fails. The js code would something like: setTimeout(function(){ $('#payForm').submit(); }, 5000); I don't know how DB+Epayment works so not sure what is their suggested workflow. – filippo Jun 28 '18 at 09:20
  • Hey bro , can you edit your answer and build the referenced code about `Timeout submit` to tackle this case . – evabb Jun 28 '18 at 09:39
  • But you haven't add the if-condition to make sure the `setTimeout(function(){ $('#payForm').submit(); }, 5000);` executes after the first form is pressed – evabb Jun 28 '18 at 10:24
  • @evabb this is not the same html page: in the first step you submit FormA (normal form submit removing all js / ajax code). This saves data to db and displays the response above. I'll update the response – filippo Jun 28 '18 at 10:42
  • I have tested .I don't know why the 5 sec auto-submit is not working .If I press enter ,I can go to the epayment gateway .Also , How can I get back the $input_amount on the previous php document ? – evabb Jun 28 '18 at 11:50
  • Also , what is the purpose of ``,`` ? Why do they include inthe second page file ? On the second form , I should only post the data to the Payment Gateway .Hence, they are not necessary to add in the second file ?Am I right ? – evabb Jun 28 '18 at 11:54
  • Do you get any errors in the javascript console? For $input_amount you can put it in FormA as an hidden field and read it back with $_POST["amount"] – filippo Jun 28 '18 at 11:56
  • JS console shows that `$('#payForm').submit();` is not defined and stop here – evabb Jun 28 '18 at 12:09
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173970/discussion-between-filippo-and-evabb). – filippo Jun 28 '18 at 12:16
0

Inside posting.done() please remove/detach the onSubmit handler for FormA just before calling the $('#FormA').submit();

posting.done(function( data ) {
     alert('success'); 
     $('#FormA').off('submit');
     $('#FormA').submit();
    });

EDIT:

Okay, why not send the formA fields with AJAX inside its onSubmit handler and submit formB from the posting.done() handler ?

<script type='text/javascript'>
  $('#formA').on('submit', function(e){
     e.preventDefault();

    /* Send the data using post with element id name and name2*/
    var posting = $.post( "<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>", { 
            field1: $('#field1').val(), 
            .....
    } );

    /* Alerts the results */
    posting.done(function( data ) {
        alert('success'); 
        $('#FormB').submit();
    }
});
</script>
IVO GELOV
  • 13,496
  • 1
  • 17
  • 26
  • It is true that it can post to formA with the ajax method .But it cannot post to the second form – evabb Jun 28 '18 at 09:36
  • Well, then I think that @filippo proposed the best solution so far – IVO GELOV Jun 28 '18 at 10:15
  • I guess some problems happened in `/* Alerts the results */ posting.done(function( data ) { alert('success'); $('#FormB').submit(); }` – evabb Jun 28 '18 at 10:15
0

If I correctly understand the question:

<script type='text/javascript'>
  $('#FormA').on('submit', function(e){
    e.preventDefault();
    $('input[type="submit"]', $(this)).attr('disabled','disabled');
    $.post( $(this).attr('action'), $(this).serialize(), function() {
        var $payForm = $("#payForm");
        $.post( $payForm.attr('action'), $payForm.serialize(), function(data) {
            alert('success');
            // redirect to whereever you want
        });
    });
  });
</script>

UPDATE:

case 2) redirecting to payment gateway:

<script type='text/javascript'>
  $("#payForm").submit(function(e) {
     alert('redirecting to payment gateway');
  }); 
  $('#FormA').on('submit', function(e){
    e.preventDefault();
    $('input[type="submit"]', $(this)).attr('disabled','disabled');
    $.post( $(this).attr('action'), $(this).serialize(), function() {
        $("#payForm").submit();
    });
  });
</script>

NOTE: replace all your script with just this one, and check in browser if requests are made in the data posted - F12 (Developer tools) - Network tab. Keep in mind that this code is written on a scratch so it may have some errors, but it shows the way.

Reflective
  • 3,854
  • 1
  • 13
  • 25
  • It is not working with your code.It cannot save data into the db and redirect to the epayment gateway . – evabb Jun 28 '18 at 11:35
  • you want the form payForm to do a regular post and redirect to PG url, then make it clear! – Reflective Jun 28 '18 at 12:06
  • I don't care which post method .I just want to press FormA submit button and post both form .(1: real form ,2 :hidden form) – evabb Jun 28 '18 at 12:08
  • you are talking about redirect to ePayment Gateway ... which means a regular post, if you do $.post you won't be redirected anywhere – Reflective Jun 28 '18 at 12:09
  • look at the `update` section if you want a redirect to PG – Reflective Jun 28 '18 at 12:18
  • should `$("#payForm").submit(function(e) {` be `firstA` ? it 's because the the submit button of payForm should not be shown – evabb Jun 28 '18 at 12:31