59

I have HTML two forms, one that submits data upon entry to a database using PHP, the other directs the user to a paypal payment page, my problem is that the user would have to submit both forms which of course I do not want them to have to do. Is there anyway to use one submit button for two forms?

(Javascript is welcome)

rid
  • 61,078
  • 31
  • 152
  • 193
Alex Saidani
  • 1,277
  • 2
  • 16
  • 31

7 Answers7

48

You should be able to do this with JavaScript:

<input type="button" value="Click Me!" onclick="submitForms()" />

If your forms have IDs:

submitForms = function(){
    document.getElementById("form1").submit();
    document.getElementById("form2").submit();
}

If your forms don't have IDs but have names:

submitForms = function(){
    document.forms["form1"].submit();
    document.forms["form2"].submit();
}
gilly3
  • 87,962
  • 25
  • 144
  • 176
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • 1
    Is it something to do with timing? Would setting a short timeout between submissions possibly address the issue? – James Johnson Oct 20 '11 at 23:49
  • Pardon my edit, but I wanted to retract my downvote. I'm not sure what happens to the request. The request is aborted by the browser for sure, but it may still go all the way through to the server. I tried debugging my local server using your technique and both pages were indeed called, so maybe your way works fine. – gilly3 Oct 20 '11 at 23:56
  • 22
    This is plain wrong (at least with Chrome and IE9)! See my answer below. – Jonas Byström Oct 29 '13 at 15:38
  • like for payment sites ? – Hitesh Sep 27 '14 at 21:09
  • Hi, I'm following this and it only submits the last form in the javascript function. Do you know what error is that? – Tri Nguyen Apr 03 '18 at 20:11
  • @TriNguyen check my answer, to submit in sequence correctly. With this code it doesn't wait for the completion of the first submit before proceeding with the second (and depending on random factors it could **sometimes** be fast enough to complete the request for both forms and **sometimes not** ). – Kamafeather May 24 '18 at 10:56
  • I am not sure why this answer is selected as the correct answer. This is absolutely wrong. Submitting one form will redirect the page, and the second form will never submit. – Rohan May 11 '20 at 21:27
  • woot m8 :P the most wrong in the answer is the confidence that you have :P – Agamemnon Katradis Nov 02 '22 at 11:39
46

A form submission causes the page to navigate away to the action of the form. So, you cannot submit both forms in the traditional way. If you try to do so with JavaScript by calling form.submit() on each form in succession, each request will be aborted except for the last submission. So, you need to submit the first form asynchronously via JavaScript:

var f = document.forms.updateDB;
var postData = [];
for (var i = 0; i < f.elements.length; i++) {
    postData.push(encodeURIComponent(f.elements[i].name) + "=" +
        encodeURIComponent(f.elements[i].value));
}
var xhr = new XMLHttpRequest();
xhr.open("POST", "mypage.php", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(postData.join("&"));

document.forms.payPal.submit();

2023 update

The original answer still works perfectly well, but here's an update using fetch() and modern syntax:

function submitBothForms() {
    const { updateDB, payPal } = document.forms;
    fetch(updateDB.action, {
        method: updateDB.method,
        headers: { "content-type": updateDB.enctype },
        body: new FormData(updateDB),
    });

    payPal.submit();
}

Note that, while normally you would await a call to fetch, we don't do it here because, since you want to submit both forms at the same time, you must not care about whether the updateDB form was successful. So, there's no point in delaying submitting the payPal form.

If that isn't what you want, you could serialize the calls, and submit the forms one after the other, adding in some error handling:

async function submitBothForms() {
    const { updateDB, payPal } = document.forms;
    const res = await fetch(updateDB.action, {
        method: updateDB.method,
        headers: { "content-type": updateDB.enctype },
        body: new FormData(updateDB),
    });
    if (!res.ok) {
        const err = new Error(`DB Update Failed! Status: ${res.status}`);
        const isJSON = res.headers.get("content-type") == "application/json";
        err.body = await (isJSON ? res.json() : res.text());
        throw err;
    }

    payPal.submit();
}

This way, if the first form is unsuccessful, an error is thrown, preventing the second form from being submitted. I'll leave handling the error and displaying error messaging to you.

gilly3
  • 87,962
  • 25
  • 144
  • 176
  • 1
    Good answer but depending on circumstances and how the forms are submitted, the submission of the first may prevent submission of the second (e.g. using the submit event on one form to call `submit()` on the other will submit the first one only in Firefox). – RobG Oct 21 '11 at 00:00
  • 1
    The second form shouldn't be submitted until the xhr object is done. – Katie Kilian Jun 13 '12 at 21:10
14

You can submit the first form using AJAX, otherwise the submission of one will prevent the other from being submitted.

RobG
  • 142,382
  • 31
  • 172
  • 209
10

In Chrome and IE9 (and I'm guessing all other browsers too) only the latter will generate a socket connect, the first one will be discarded. (The browser detects this as both requests are sent within one JavaScript "timeslice" in your code above, and discards all but the last request.)

If you instead have some event callback do the second submission (but before the reply is received), the socket of the first request will be cancelled. This is definitely nothing to recommend as the server in that case may well have handled your first request, but you will never know for sure.

I recommend you use/generate a single request which you can transact server-side.

Jonas Byström
  • 25,316
  • 23
  • 100
  • 147
8

The currently chosen best answer is too fuzzy to be reliable.

This feels to me like a fairly safe way to do it:

(Javascript: using jQuery to write it simpler)

$('#form1').submit(doubleSubmit);

function doubleSubmit(e1) {
    e1.preventDefault();
    e1.stopPropagation();
    var post_form1 = $.post($(this).action, $(this).serialize());

    post_form1.done(function(result) {
            // would be nice to show some feedback about the first result here
            $('#form2').submit();
        });
};

Post the first form without changing page, wait for the process to complete. Then post the second form. The second post will change the page, but you might want to have some similar code also for the second form, getting a second deferred object (post_form2?).

I didn't test the code, though.

Kamafeather
  • 8,663
  • 14
  • 69
  • 99
  • Why a downvote? A comment would be better appreciated, if I wrote something wrong. – Kamafeather Jun 01 '17 at 11:05
  • Why are you using both `e1.preventDefault();` and `e1.stopPropagation();`. i guess either of them would have suffice. FYI i didn't downvote. Its just that i reached this page and have some doubt. – dev_khan Feb 19 '18 at 06:40
  • 1
    @dev_khan they provide different functionality so, nope, not either of them would have suffice. ```preventDefault``` is for sure needed, in order to prevent the default *submit* and take ownership of what will happen with that event. ```stopPropagation``` instead depends on the use case, in case the event shouldn't be caught from outer elements (can't recall, but probably last year I put it *-while coding on the fly-* just to be safe ). And don't worry I didn't think you downvoted (is still a mistery why I got it), but thank you for specifying it – Kamafeather Mar 06 '18 at 11:55
-2

if you want to submit two forms with one button you need to do this:

1- use setTimeout()

2- allow show pop up

<script>
function myFunction() {
setTimeout(function(){ document.getElementById("form1").submit();}, 3000);   
setTimeout(function(){ document.getElementById("form2").submit();}, 6000);   
}
</script>
<form  target="_blank" id="form1">
<input type="text">
<input type="submit">
</form>
<form target="_blank" id="form2">
<input type="text">
<input type="submit">
</form>

javascript doesn't submit two forms at the same time. we submit two forms with one button not at the same time but after secounds.

edit: when we use this code, browser doesn't allow pop up.
if you use this code for your software like me just set browser for show pop up but if you use it in designing site, browser is a barrier and code doesn't run.

rezaSefiddashti
  • 134
  • 1
  • 9
  • 2
    Waiting is not informing if the first submit was successful or not (depending on the workflow the second form could need to prevent submitting then), nor is giving any guarantee of the sequential processing of the two requests (e.g. should I store the transaction in the database if the PayPal transaction has failed?). Take a look to the alternative answer I wrote; I tried to gives more control on workflow and results. – Kamafeather Jun 01 '17 at 11:00
-3

If you have a regular submit button, you could add an onclick event to it that does the follow:

document.getElementById('otherForm').submit();
endyourif
  • 2,186
  • 19
  • 33