Deux boutons de soumission dans un seul formulaire


534

J'ai deux boutons de soumission dans un formulaire. Comment déterminer lequel a été touché côté serveur?


Envisagez de remplacer la réponse acceptée par celle de Parrots .
Peter Mortensen

2
@PeterMortensen - Ni la réponse acceptée ni la réponse de Parrot ne sont les meilleures aujourd'hui. Voir la réponse de Leo pour la nouvelle solution HTML5 utilisant l'attribut formaction. Ou voir la réponse de kiril pour savoir comment rendre le HTML visible pour l'utilisateur indépendamment de la valeur envoyée au navigateur - résoudre le problème d'internationalisation d'une manière plus facile à coder que la réponse de Greg ou de Parrot.
ToolmakerSteve

Réponses:


448

Si vous donnez à chacun un nom, celui sur lequel vous cliquez sera envoyé comme n'importe quelle autre entrée.

<input type="submit" name="button_1" value="Click me">

101
Assurez-vous également que le nom du bouton a un nom correct! Par exemple, "bouton-1" ne fonctionnerait PAS. Peut sauver quelqu'un beaucoup de tracas, alors gardez cela à l'esprit.
pdolinaj du

22
Normalement, toutes les entrées du formulaire sont envoyées avec le formulaire. Étant donné que la valeur d'un bouton n'est soumise que si vous cliquez dessus, vous devez rechercher les valeurs de formulaire pour ces noms prédéfinis. Je pense que l'autre réponse ( stackoverflow.com/a/21778226/88409 ) qui implique de leur donner tous le même nom, avec des valeurs différentes, a plus de sens. Ensuite, il vous suffit de saisir la valeur sous un seul nom de champ de formulaire connu. Cela rend également plus évident qu'une seule valeur (celle sur laquelle vous avez cliqué) sera envoyée pour le nom d'entrée donné, un peu comme le fonctionnement des boutons radio (même nom, valeurs différentes).
Triynko

6
@Triynko, comme l'a dit Robin Green dans les commentaires de cette réponse, celle-ci est meilleure pour l'internationalisation. Par exemple, si la page est rendue en espagnol, le texte des boutons sera probablement différent. Donc, avoir la logique de votre code dépend du texte de ce bouton se cassera dans ce cas. Aller par le nom est plus sûr, car c'est une valeur qui n'est pas affichée pour l'utilisateur et peut donc être traitée plus comme une variable "privée" et moins comme un message aux utilisateurs.
sfarbota

Pour clarifier le commentaire de @ sfarbota: La première solution présentée dans la réponse de Parrot est problématique, car elle repose sur le test de la valeur visible par l' utilisateur . C'est douteux - le code qui se casse lors de la modification d'un mot visible par l'utilisateur est considéré comme "fragile". La deuxième solution présentée dans la réponse de Parrot est très bien - c'est la même que celle-ci. La deuxième solution de Parrot montre également le code correspondant à écrire, c'est donc une réponse plus utile que celle-ci.
ToolmakerSteve

2
Voir la réponse de Leo pour la nouvelle solution HTML5 utilisant l'attribut formaction. Ou voir la réponse de kiril pour savoir comment rendre le HTML visible pour l'utilisateur indépendamment de la valeur envoyée au navigateur - résoudre le problème d'internationalisation.
ToolmakerSteve

875

Solution 1:
attribuez à chaque entrée une valeur différente et conservez le même nom:

<input type="submit" name="action" value="Update" />
<input type="submit" name="action" value="Delete" />

Ensuite, dans la vérification du code pour voir lequel a été déclenché:

if ($_POST['action'] == 'Update') {
    //action for update here
} else if ($_POST['action'] == 'Delete') {
    //action for delete
} else {
    //invalid action!
}

Le problème est que vous liez votre logique au texte visible par l'utilisateur dans l'entrée.


Solution 2:
donnez à chacun un nom unique et vérifiez la présence de cette entrée dans $ _POST:

<input type="submit" name="update_button" value="Update" />
<input type="submit" name="delete_button" value="Delete" />

Et dans le code:

if (isset($_POST['update_button'])) {
    //update action
} else if (isset($_POST['delete_button'])) {
    //delete action
} else {
    //no button pressed
}

37
Aux fins de i18n, il pourrait être préférable d'utiliser la réponse sélectionnée.
Robin Green

11
@LaszloPapp comme l'indique la réponse elle-même, si vous utilisez la réponse sélectionnée ci-dessus, vous pouvez internationaliser le formulaire (c'est-à-dire traduire dans différentes langues ou dialectes) sans affecter la logique. Si vous utilisez la première option dans cette réponse, la logique dépend de la langue dans laquelle le formulaire est réellement présenté.
Robin Green

1
@RobinGreen: Je pense que la plupart des gens utiliseront la deuxième logique, n'est-ce pas?
lpapp

5
i18n = i [nternationalizatio] n, et le 18 représente les 18 lettres entre la première et la dernière.
Buttle Butkus

18
L'OP n'a pas demandé PHP.
Rudey

110

Une solution encore meilleure consiste à utiliser des balises de bouton pour envoyer le formulaire:

<form>
    ...
    <button type="submit" name="action" value="update">Update</button>
    <button type="submit" name="action" value="delete">Delete</button>
</form>

Le code HTML à l' intérieur du bouton (par exemple, ..>Update<..est ce qui est vu par l'utilisateur; parce qu'il y a du code HTML fourni, il valuen'est pas visible par l'utilisateur; il est uniquement envoyé au serveur. De cette façon, il n'y a aucun inconvénient avec l'internationalisation et les langues d'affichage multiples (dans le ancienne solution, le libellé du bouton est également la valeur envoyée au serveur).


13
Apparemment, le comportement du navigateur diffère; certains soumettent l'attribut value, d'autres la chaîne entre les balises ... Soyez donc prudent avec celui-ci.
Jeroen Dierckx

1
Je pense que l'extrait fourni est entièrement pris en charge ( w3schools.com/tags/att_button_type.asp )
kiril

2
@kiril l'extrait de ce lien utilise deux types différents de <button>: submitet reset. Notez que resetcela ne soumet rien, il réinitialise simplement le formulaire. L'argument de Jeroen demeure donc.
fizruk

7
D'accord, tu as raison. Ensuite, j'ai vérifié le brouillon de travail HTML5 W3C. Citation: >> L'attribut value donne la valeur de l'élément aux fins de la soumission du formulaire. La valeur de l'élément est la valeur de l'attribut value de l'élément, s'il y en a un, ou la chaîne vide sinon. >> REMARQUE: Un bouton (et sa valeur) n'est inclus dans la soumission du formulaire que si le bouton lui-même a été utilisé pour lancer la soumission du formulaire.
kiril

8
@Jeroen Bull. Quels navigateurs soumettent le texte entre les balises? Une entrée ou un bouton ne doit soumettre que l'attribut 'value'. Un bouton peut littéralement avoir n'importe quoi entre ses balises, y compris des images ou d'autres balises HTML. C'est tout l'intérêt d'utiliser un bouton sur un élément d'entrée, et vous essayez de suggérer que le navigateur va vider tout ce contenu en tant que valeur? En aucune façon.
Triynko

93

Il y a une nouvelle approche HTML5 à cela, l' formactionattribut:

<button type="submit" formaction="/action_one">First action</button>
<button type="submit" formaction="/action_two">Second action</button>

Apparemment, cela ne fonctionne pas dans IE9 et versions antérieures, mais pour les autres navigateurs, cela devrait aller (voir: w3schools.com HTML <button> Formaction Attribute ).

Personnellement, j'utilise généralement Javascript pour soumettre des formulaires à distance (pour une rétroaction perçue plus rapide) avec cette approche comme sauvegarde. Entre les deux, les seules personnes non couvertes sont IE <9 avec Javascript désactivé.

Bien sûr, cela peut être inapproprié si vous effectuez essentiellement la même action côté serveur, quel que soit le bouton enfoncé, mais souvent, si deux actions côté utilisateur sont disponibles, elles seront également mappées sur deux actions côté serveur.

Edit: Comme noté par Pascal_dher dans les commentaires, cet attribut est également disponible sur la <input>balise.


1
Également disponible pour la balise "input". Accoding à w3schools: lors de l'utilisation de la balise bouton, différents navigateurs peuvent soumettre des valeurs différentes: w3schools.com/tags/tag_button.asp
Pascal_dher

3
Je suis développeur Web depuis 12 ans et celui-ci est nouveau pour moi et était exactement ce dont j'avais besoin, en fait. Merci!
KyleFarris

1
Vous êtes les bienvenus @KyleFarris! Je crois que cela n'est devenu possible que relativement récemment, donc pas de surprise si vous ne l'avez pas encore rencontré.
Leo

2
Remarque pour les utilisateurs de Rails: l'ajout de cet attribut ne fonctionnera pas si votre formulaire est créé à l'aide de form_tag. La seule façon de le faire fonctionner est de passer à form_foret d'utiliser f.submit formaction: 'your_path'.
fgblomqvist


27

C'est extrêmement facile à tester

<form action="" method="get">

<input type="submit" name="sb" value="One">
<input type="submit" name="sb" value="Two">
<input type="submit" name="sb" value="Three">

</form>

Il suffit de mettre cela dans une page HTML, de cliquer sur les boutons et de regarder l'URL


5
Utiliser GET ici est une mauvaise pratique, il faut utiliser POST lorsque cela est possible.
Syncrossus

6
@Syncrossus C'est à des fins de test.
Etienne Martin

22

Utilisez l' formactionattribut HTML (5ème ligne):

<form action="/action_page.php" method="get">
    First name: <input type="text" name="fname"><br>
    Last name: <input type="text" name="lname"><br>
    <button type="submit">Submit</button><br>
    <button type="submit" formaction="/action_page2.php">Submit to another page</button>
</form>


@ToolmakerSteve - Mais les utilisateurs ont voté positivement . faites votre choix!!
user12379095

21
<form>
    <input type="submit" value="Submit to a" formaction="/submit/a">
    <input type="submit" value="submit to b" formaction="/submit/b">    
</form>

Fonction HTML5. Fonctionne parfaitement sur les navigateurs Web récents, merci!
Stephane Lallemagne

1
REMARQUE: Cela semble être la même que la réponse précédente de Leo , sauf qu'elle montre l'utilisation de la inputbalise plutôt que la buttonbalise.
ToolmakerSteve

11

La meilleure façon de gérer plusieurs boutons d'envoi consiste à utiliser la casse du commutateur dans le script du serveur

<form action="demo_form.php" method="get">

Choose your favorite subject:

<button name="subject" type="submit" value="html">HTML</button>
<button name="subject" type="submit" value="css">CSS</button>
<button name="subject" type="submit" value="javascript">Java Script</button>
<button name="subject" type="submit" value="jquery">jQuery</button>

</form>

code serveur / script serveur - où vous soumettez le formulaire:

demo_form.php

<?php

switch($_REQUEST['subject']) {

    case 'html': //action for html here
                break;

    case 'css': //action for css here
                break;

    case 'javascript': //action for javascript here
                        break;

    case 'jquery': //action for jquery here
                    break;
}

?>

Source: W3Schools.com


oui c'est que vous devez avoir une idée sur les scripts d'action (technologie de script côté serveur) Vous pouvez utiliser n'importe quel script / fichier pour traiter les données soumises, par exemple php, asp, jsp, etc. <form action="demo_form.php" method="get">
Shailesh Sonare

D'accord. C'était déroutant car il existe également un langage nommé ActionScript. Vous devriez plutôt dire: "code serveur" ou "script serveur".
Civil

Je ne savais pas que tu pouvais faire ça avec des boutons
William Isted

10

Peut-être que les solutions suggérées ici ont fonctionné en 2009, mais ive a testé toutes ces réponses votées et personne ne travaille dans aucun navigateur.

la seule solution que j'ai trouvée fonctionne est la suivante: (mais c'est un peu moche à utiliser je pense)

<form method="post" name="form">
<input type="submit" value="dosomething" onclick="javascript: form.action='actionurl1';"/>
<input type="submit" value="dosomethingelse" onclick="javascript: form.action='actionurl2';"/>


2
Pourquoi ne pas simplement utiliser formaction="actionurl1"? Vous n'avez pas besoin de JavaScript.
rybo111

3
@ rybo111 Le navigateur IE9 (la sorcière est relativement largement utilisée) ne prend pas en chargeformaction
clueless007

1
@inaliaghle True, c'est environ 1% des utilisateurs - cela dépend à qui le projet est destiné. Environ 1% des utilisateurs n'utilisent pas JavaScript.
rybo111

1
Pour les futurs lecteurs: il n'y a rien de mal à utiliser javascript, comme dans cette réponse. C'est une compétence utile à savoir. OTOH, les réponses les plus votées fonctionnent également bien - ignorez la phrase principale de cette réponse. Si, pour une raison quelconque, vous ne parvenez pas à obtenir ces autres réponses, postez votre code complet sous forme de question SO, expliquez ce qui se passe (ou ne se produit pas) et demandez ce que vous faites de mal.
ToolmakerSteve

6

Définissez namecomme array.

<form action='' method=POST>
    (...) some input fields (...)
    <input type=submit name=submit[save] value=Save>
    <input type=submit name=submit[delete] value=Delete>
</form>

Exemple de code serveur (PHP):

if (isset($_POST["submit"])) {
    $sub = $_POST["submit"];

    if (isset($sub["save"])) {
        // save something;
    } elseif (isset($sub["delete"])) {
        // delete something
    }
}

elseiftrès important, car les deux seront analysés sinon. Prendre plaisir.


Maintenant, c'est une excellente suggestion - principalement parce que vous pouvez ajouter plus de boutons avec plus de cas très facilement, et utiliser un switchavec une action par défaut si l'on a ajouté un bouton et oublié de l'ajouter au switch(et / ou quelque chose de mal orthographié, etc.)
Gwyneth Llewelyn

De plus, @Pato a ajouté une réponse similaire qui est peut-être plus idiomatique, mais la vôtre fonctionne très bien!
Gwyneth Llewelyn

1
@GwynethLlewelyn Je n'ai pas vu l'autre réponse ou je n'ai pas remarqué quand j'ai écrit la mienne. C'est en fait la même chose, mais cela souligne simplement comment la plupart des gens préfèrent cette logique. La différence est juste avec les noms pour des raisons sémantiques, une bonne compréhension pour les débutants ou ceux qui aiment commencer avec.
Thielicious

5

Puisque vous n'avez pas spécifié la méthode de script côté serveur que vous utilisez, je vais vous donner un exemple qui fonctionne pour Python, en utilisant CherryPy (bien que cela puisse être utile dans d'autres contextes également):

<button type="submit" name="register">Create a new account</button>
<button type="submit" name="login">Log into your account</button>

Plutôt que d'utiliser la valeur pour déterminer le bouton sur lequel vous avez appuyé, vous pouvez utiliser le nom (avec la <button>balise au lieu de <input>). De cette façon, si vos boutons ont le même texte, cela ne causera pas de problèmes. Les noms de tous les éléments du formulaire, y compris les boutons, sont envoyés dans le cadre de l'URL. Dans CherryPy, chacun d'eux est un argument pour une méthode qui fait le code côté serveur. Donc, si votre méthode n'a **kwargsque sa liste de paramètres (au lieu de taper fastidieusement chaque nom de chaque élément de formulaire), vous pouvez vérifier quel bouton a été enfoncé comme ceci:

if "register" in kwargs:
    pass #Do the register code
elif "login" in kwargs:
    pass #Do the login code

3
<form method="post">
<input type="hidden" name="id" value="'.$id.'" readonly="readonly"/>'; //any value to post PHP
<input type='submit' name='update' value='update' formAction='updateCars.php'/>
<input type='submit' name='delete' value='delete' formAction='sqlDelete.php'/>
</form>

2

Je pense que vous devriez pouvoir lire le nom / la valeur dans votre tableau GET. Je pense que le bouton qui n'a pas été cliqué n'apparaîtra pas dans cette liste.


Vous voulez probablement dire le tableau POST.
ypnos

3
Pas nécessairement, si la méthode du formulaire est "POST", elle n'apparaîtra pas dans le tableau GET. La plupart des formulaires sont soumis via POST.
Parrots

2
Soit / ou est techniquement correct, et pourtant si faux. Vous pouvez soumettre un formulaire avec method = "GET", mais il est digne de foi.
Bill le lézard

4
Il n'est "digne de mention" que lorsqu'il est utilisé de manière inappropriée: w3.org/2001/tag/doc/whenToUseGet.html .
mercator

2
Oui, je n'essayais pas de suggérer GET, j'essayais simplement de généraliser les choses.
John Bubriski

1

Vous pouvez aussi le faire comme ça (je pense que c'est très pratique si vous avez N entrées).

<input type="submit" name="row[456]" value="something">
<input type="submit" name="row[123]" value="something">
<input type="submit" name="row[789]" value="something">

Un cas d'utilisation courant consisterait à utiliser différents identifiants d'une base de données pour chaque bouton, afin que vous puissiez plus tard savoir sur le serveur sur quelle ligne vous avez cliqué.

Côté serveur (PHP dans cet exemple), vous pouvez lire "row" comme un tableau pour obtenir l'identifiant. $_POST['row']sera un tableau avec un seul élément, sous la forme [ id => value ](par exemple:) [ '123' => 'something' ].

Donc, pour obtenir l'ID cliqué, vous faites:

$index = key($_POST['row']);

http://php.net/manual/en/function.key.php


Ceci est similaire à la réponse publiée sur @Thielicious , mais la vôtre est peut-être plus idiomatique. Personnellement, je préfère utiliser des balises alphanumériques pour l'index (par opposition aux nombres) pour la lisibilité (plus facile à retenir ce que chaque bouton est censé faire), mais YMMV. Mais profiter d' $_POST['row']être un tableau associatif est intelligent!
Gwyneth Llewelyn

1
Je suis d'accord que si vous avez affaire à des boutons statiques, vous devez utiliser des clés nommées. Mais dans certains cas, vous ne pouvez pas. Parfois, vous générez ces entrées de manière dynamique. Le cas le plus courant serait une liste de lignes, chacune identifiée par un identifiant. Je pense que je pensais à ce cas quand j'ai écrit la réponse (il y a 4 ans!). Je l'ai édité, il est donc plus évident que le numéro est un identifiant et non un index.
Pato

Bien joué! Oui, je suis d'accord, c'est plus évident maintenant; Je crois toujours que votre réponse est légèrement meilleure que celle de @Thielicious (et peut-être même un peu plus efficace, surtout s'il y a beaucoup de boutons).
Gwyneth Llewelyn

1

Vous formaction pour plusieurs bouton de soumission dans un exemple de formulaire

 <input type="submit" name="" class="btn action_bg btn-sm loadGif" value="Add Address" title="" formaction="/addAddress"> 
 <input type="submit" name="" class="btn action_bg btn-sm loadGif" value="update Address" title="" formaction="/updateAddress"> 

0

Simple, vous pouvez modifier l'action du formulaire sur différents boutons de soumission Cliquez sur.

Essayez ceci dans le document.

$(".acceptOffer").click(function () {
       $("form").attr("action", "/Managers/SubdomainTransactions");
});

$(".declineOffer").click(function () {
       $("form").attr("action", "/Sales/SubdomainTransactions");
});

0

Vous pouvez également utiliser un attribut href et envoyer un get avec la valeur ajoutée pour chaque bouton. Mais le formulaire ne serait alors pas requis

href="/SubmitForm?action=delete"
href="/SubmitForm?action=save"

Cela ne fonctionnerait pas pour les contrôleurs sous POSTroutes.
Xavi Montero

par conséquent, "envoyez un get"
Jonathan Laliberte

3
Je suis désolé de ne pas être d'accord, mais GETne convient pas toujours. Si vous "modifiez l'état de votre modèle", vous ne devez jamais utiliser un GET, car l'actualisation du navigateur pourrait entraîner l'envoi transparent de deux fois la même demande. Utilisez GETuniquement pour "visualiser" les choses et POSTpour envoyer des demandes de changements d'état (ajouter, supprimer, modifier, etc.). puis dans votre POSTaction de contrôleur, modifiez l'état (base de données, sesion ...) et lancez une redirection-réponse qui est alors GETle nouvel état modifié. Faire GETpour la modification de l'état du modèle est très sale et tout bon codeur devrait l'éviter. Désolé de le dire. Nettoyer le code rulez.
Xavi Montero

Vrai. Mais jouer sale peut parfois être propre. Cela dépend de ce que vous faites exactement. Personnellement , il ne serait pas la carte des demandes de suppression et de modifier un get, mais il existe des moyens pour le faire fonctionner .. comme vérifier si elle a déjà été supprimé, ou vérifier si l'utilisateur a la permission de le faire , etc ...
Jonathan Laliberté

-1

Vous pouvez présenter les boutons comme ceci:

<input type="submit" name="typeBtn" value="BUY">
<input type="submit" name="typeBtn" value="SELL">

Et puis dans le code, vous pouvez obtenir la valeur en utilisant:

if request.method == 'POST':
    #valUnits = request.POST.get('unitsInput','')
    #valPrice = request.POST.get('priceInput','')
    valType = request.POST.get('typeBtn','')

(valUnits et valPrice sont quelques autres valeurs que j'extrais du formulaire que j'ai laissé pour illustration)


-1

Puisque vous n'avez pas spécifié la méthode de script côté serveur que vous utilisez, je vais vous donner un exemple qui fonctionne pour PHP

<?php
   if(isset($_POST["loginForm"]))
   {
    print_r ($_POST); // FOR Showing POST DATA
   }
   elseif(isset($_POST["registrationForm"]))
   {
    print_r ($_POST);
   }
   elseif(isset($_POST["saveForm"]))
   {
    print_r ($_POST);
   }
   else{

   }
?>
<html>
<head>
</head>
<body>
  
  <fieldset>
    <legend>FORM-1 with 2 buttons</legend>
      <form method="post" >
      <input type="text" name="loginname" value ="ABC" >

     <!--Always use type="password" for password --> 
     <input type="text" name="loginpassword" value ="abc123" >
     
     <input type="submit" name="loginForm" value="Login"><!--SUBMIT Button 1 -->
     <input type="submit" name="saveForm" value="Save">  <!--SUBMIT Button 2 -->
   </form>
  </fieldset>



  <fieldset>
    <legend>FORM-2 with 1 button</legend>
     <form method="post" >
      <input type="text" name="registrationname" value ="XYZ" >
      
     <!--Always use type="password" for password -->
     <input type="text" name="registrationpassword" value ="xyz123" >
     
     <input type="submit" name="registrationForm" value="Register"> <!--SUBMIT Button 3 -->
   </form>
  </fieldset>
  

</body>
</html>

Formes

Lorsque vous cliquez sur Connexion -> loginForm

Lorsque vous cliquez sur Enregistrer -> saveForm

Lorsque vous cliquez sur Register -> registrationForm

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.