60 votes

Soumettre deux formulaires avec un seul bouton

J'ai deux formulaires HTML, l'un qui soumet des données à une base de données en utilisant PHP, l'autre qui dirige l'utilisateur vers une page de paiement paypal. Mon problème est que l'utilisateur devrait soumettre les deux formulaires, ce que je ne veux évidemment pas qu'il ait à faire. Existe-t-il un moyen d'utiliser un bouton d'envoi pour deux formulaires ?

(Javascript est le bienvenu)

49voto

gilly3 Points 33285

L'envoi d'un formulaire entraîne la navigation de la page vers l'adresse suivante action de la forme. Vous ne pouvez donc pas soumettre les deux formulaires de la manière traditionnelle. Si vous essayez de le faire avec JavaScript en appelant form.submit() sur chaque formulaire successivement, chaque demande sera interrompue, à l'exception de la dernière soumission. Vous devez donc soumettre le premier formulaire de manière asynchrone via JavaScript :

var f = document.forms.updateDB;
var postData = [];
for (var i = 0; i < f.elements.length; i++) {
    postData.push(f.elements[i].name + "=" + 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();

1 votes

Bonne réponse mais, selon les circonstances et la façon dont les formulaires sont soumis, la soumission du premier peut empêcher la soumission du second (par exemple, en utilisant l'événement submit d'un formulaire pour appeler submit() l'autre soumettra la première uniquement dans Firefox).

1 votes

Le second formulaire ne devrait pas être soumis avant que l'objet xhr soit terminé.

47voto

James Johnson Points 29414

Vous devriez être en mesure de le faire avec JavaScript :

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

Si vos formulaires ont des identifiants :

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

Si vos formulaires n'ont pas d'identifiants mais des noms :

submitForms = function(){
    document.forms["form1"].submit();
    document.forms["form2"].submit();
}

1 votes

Est-ce que cela a quelque chose à voir avec le timing ? La mise en place d'un court délai entre les soumissions pourrait-elle résoudre le problème ?

0 votes

Pardonnez mon édition, mais je voulais revenir sur mon downvote. Je ne suis pas sûr de ce qui arrive à la requête. La requête est interrompue par le navigateur, c'est sûr, mais elle peut encore aller jusqu'au serveur. J'ai essayé de déboguer mon serveur local en utilisant votre technique et les deux pages ont bien été appelées, donc peut-être que votre méthode fonctionne bien.

22 votes

C'est tout simplement faux (au moins avec Chrome et IE9) ! Voir ma réponse ci-dessous.

14voto

RobG Points 41170

Vous pouvez soumettre le premier formulaire en utilisant AJAX, sinon la soumission de l'un empêchera la soumission de l'autre.

10voto

Jonas Byström Points 5106

Dans Chrome et IE9 (et je suppose que tous les autres navigateurs aussi), seule la dernière demande générera une connexion de socket, la première sera rejetée. (Le navigateur détecte cela car les deux requêtes sont envoyées dans un même "timeslice" JavaScript dans votre code ci-dessus, et rejette toutes les requêtes sauf la dernière).

Si, à la place, vous demandez à un callback d'événement d'effectuer la deuxième soumission (mais avant que la réponse ne soit reçue), le socket de la première demande sera annulé. Ceci est définitivement Rien à recommander car le serveur dans ce cas peut très bien avoir traité votre première demande, mais vous ne pourrez jamais en être sûr.

Je vous recommande d'utiliser/générer une seule requête que vous pouvez traiter côté serveur.

0 votes

L'utilisation de promesses ou d'objets différés est également une alternative intéressante.

9voto

Kamafeather Points 179

La meilleure réponse actuellement choisie est trop floue pour être fiable.

Cela me semble être un moyen assez sûr de le faire :

(Javascript : utiliser jQuery pour simplifier l'écriture)

$('#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();
        });
};

Postez le premier formulaire sans changer de page, attendez que le processus se termine. Puis postez le deuxième formulaire. Le deuxième formulaire changera la page, mais vous voudrez peut-être avoir un code similaire pour le deuxième formulaire, en obtenant un deuxième objet différé ( post_form2 ?).

Je n'ai pas testé le code, cependant.

0 votes

Pourquoi un downvote ? Un commentaire serait plus apprécié, si j'ai écrit quelque chose de mal.

0 votes

Pourquoi utilisez-vous les deux e1.preventDefault(); y e1.stopPropagation(); Je pense que l'un ou l'autre aurait suffi. Pour info, je n'ai pas voté à la baisse. C'est juste que j'ai atteint cette page et j'ai quelques doutes.

1 votes

@dev_khan ils fournissent des fonctionnalités différentes donc, non, aucun des deux n'aurait suffi. preventDefault est assurément nécessaire, afin d'éviter que l'option par défaut soumettre et s'approprier ce qui va se passer avec cet événement. stopPropagation au lieu de cela dépend du cas d'utilisation, dans le cas où l'événement ne doit pas être attrapé à partir d'éléments extérieurs (je ne me souviens pas, mais probablement l'année dernière je l'ai mis - tout en codant à la volée juste pour être sûr). Et ne vous inquiétez pas, je ne pensais pas que vous aviez rétrogradé (je ne sais toujours pas pourquoi je l'ai reçu), mais merci de l'avoir précisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X