Due pulsanti di invio in un unico modulo


534

Ho due pulsanti di invio in un modulo. Come faccio a determinare quale è stato colpito sul lato server?


Valuta la possibilità di cambiare la risposta accettata alla risposta di Parrots .
Peter Mortensen,

2
@PeterMortensen - Né la risposta accettata né quella di Parrot sono le migliori oggi. Vedi la risposta di Leo per la più recente soluzione HTML5 usando l'attributo formaction. Oppure vedi la risposta di Kiril su come rendere l'HTML visibile all'utente sia indipendente dal valore inviato al browser, risolvendo il problema dell'internazionalizzazione in un modo più semplice da programmare rispetto alla risposta di Greg o Parrot.
ToolmakerSteve

Risposte:


448

Se dai a ciascuno un nome, quello cliccato verrà inviato come qualsiasi altro input.

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

101
Assicurati anche che il nome del pulsante abbia il nome corretto! Ad esempio, "button-1" NON funzionerebbe. Può salvare qualcuno un sacco di problemi, quindi tienilo a mente.
pdolinaj,

22
Normalmente, tutti gli input nel modulo vengono inviati con il modulo. Poiché il valore di un pulsante viene inviato solo se si fa clic, è necessario cercare i valori del modulo per questi nomi predefiniti. Penso che l'altra risposta ( stackoverflow.com/a/21778226/88409 ) che prevede di dare loro lo stesso nome, con valori diversi, abbia più senso. Quindi prendi semplicemente il valore sotto un singolo nome di campo del modulo noto. Rende inoltre più ovvio che verrà inviato un solo valore (quello cliccato) per il nome di input specificato, proprio come il funzionamento dei pulsanti di opzione (stesso nome, valori diversi).
Triynko,

6
@Triynko, come ha detto Robin Green nei commenti di quella risposta, questa è migliore per l'internazionalizzazione. Ad esempio, se la pagina viene visualizzata in spagnolo, il testo dei pulsanti sarà probabilmente diverso. Quindi avere la logica del tuo codice dipende dal testo di quel pulsante si romperà in quel caso. Andare con il nome è più sicuro, in quanto è un valore che non viene visualizzato per l'utente e quindi può essere trattato più come una variabile "privata" e meno come un messaggio per gli utenti.
sfarbota,

Per chiarire il commento di @ sfarbota: la prima soluzione mostrata nella risposta di Parrot è problematica, poiché si basa sul test del valore visibile dall'utente . Ciò è dubbio: il codice che si interrompe quando si cambia una parola visibile dall'utente è considerato "fragile". La seconda soluzione mostrata nella risposta di Parrot va bene - è la stessa di questa. La seconda soluzione di Parrot mostra anche il codice corrispondente da scrivere, quindi è una risposta più utile di questa.
ToolmakerSteve

2
Vedi la risposta di Leo per la più recente soluzione HTML5 usando l'attributo formaction. Oppure vedi la risposta di Kiril su come rendere l'HTML visibile all'utente sia indipendente dal valore inviato al browser, risolvendo il problema dell'internazionalizzazione.
ToolmakerSteve

875

Soluzione 1:
assegnare a ciascun input un valore diverso e mantenere lo stesso nome:

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

Quindi nel controllo del codice per vedere quale è stato attivato:

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

Il problema è che leghi la tua logica al testo visibile dall'utente all'interno dell'input.


Soluzione 2:
assegnare a ciascuno un nome univoco e controllare $ _POST per l'esistenza di tale input:

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

E nel codice:

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

37
Ai fini di i18n potrebbe essere meglio utilizzare la risposta selezionata.
Robin Green,

11
@LaszloPapp come dice la risposta stessa, se usi la risposta selezionata sopra, puoi internazionalizzare il modulo (cioè tradurre in diverse lingue o dialetti) senza influire sulla logica. Se usi la prima opzione in questa risposta, la logica dipende dalla lingua in cui il modulo è effettivamente presentato.
Robin Green

1
@RobinGreen: penso che molte persone useranno la seconda logica, no?
lpapp,

5
i18n = i [nternationalizatio] n, e il 18 rappresenta le 18 lettere tra il primo e l'ultimo.
Buttle Butkus,

18
L'OP non ha chiesto PHP.
Rudey,

110

Una soluzione ancora migliore consiste nell'utilizzare i tag dei pulsanti per inviare il modulo:

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

L'HTML all'interno del pulsante (ad es. ..>Update<..È ciò che viene visualizzato dall'utente; poiché è fornito HTML, valuenon è visibile all'utente; viene inviato solo al server. In questo modo non ci sono inconvenienti con l'internazionalizzazione e più lingue di visualizzazione (nella prima soluzione, l'etichetta del pulsante è anche il valore inviato al server).


13
Apparentemente il comportamento del browser differisce; alcuni inviano l'attributo value, altri la stringa tra i tag ... Quindi fai attenzione con questo.
Jeroen Dierckx,

1
Credo che il frammento di codice fornito è pienamente supportato ( w3schools.com/tags/att_button_type.asp )
Kiril

2
@kiril lo snippet di quel link utilizza due diversi tipi di <button>: submite reset. Nota che resetnon invia nulla, reimposta il modulo. Quindi l'argomento di Jeroen rimane.
Fizruk,

7
Ok, hai ragione. Quindi, ho controllato la bozza di lavoro HTML5 W3C. Citazioni: >> L'attributo value fornisce il valore dell'elemento ai fini dell'invio del modulo. Il valore dell'elemento è il valore dell'attributo value dell'elemento, se presente, oppure la stringa vuota in caso contrario. >> NOTA: un pulsante (e il suo valore) è incluso nell'invio del modulo solo se il pulsante stesso è stato utilizzato per avviare l'invio del modulo.
Kiril,

8
@Jeroen Bull. Quali browser inviano il testo tra i tag? Un input o un pulsante deve sempre e solo inviare l'attributo 'valore'. Un pulsante potrebbe letteralmente avere qualcosa tra i tag, comprese le immagini o altri tag HTML. Questo è il punto centrale dell'uso di un pulsante su un elemento di input e stai cercando di suggerire che il browser scaricherà tutto quel contenuto come valore? Non c'è modo.
Triynko,

93

C'è un nuovo approccio HTML5 a questo, l' formactionattributo:

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

Apparentemente questo non funziona in IE9 e precedenti, ma per altri browser dovresti andare bene (vedi: w3schools.com HTML <button> attributo formazione ).

Personalmente, generalmente utilizzo Javascript per inviare moduli in remoto (per un feedback percepito più velocemente) con questo approccio come backup. Tra i due, le uniche persone non coperte sono IE <9 con Javascript disabilitato.

Naturalmente, ciò potrebbe essere inappropriato se in pratica si esegue la stessa azione sul lato server indipendentemente dal pulsante premuto, ma spesso se sono disponibili due azioni sul lato utente, verranno mappate anche su due azioni sul lato server.

Modifica: come osservato da Pascal_dher nei commenti, questo attributo è disponibile anche sul <input>tag.


1
Disponibile anche per il tag "input". Accodamento a w3schools: quando si utilizzano i tag dei pulsanti, diversi browser possono inviare valori diversi: w3schools.com/tags/tag_button.asp
Pascal_dher

3
Sono uno sviluppatore web da 12 anni e questo è nuovo per me ed era esattamente quello di cui avevo bisogno, in realtà. Grazie!
KyleFarris,

1
Prego @KyleFarris! Credo che questo sia diventato possibile solo relativamente di recente, quindi nessuna sorpresa se non l'avessi ancora incontrato.
Leone,

2
Nota per gli utenti di Rails: l'aggiunta di questo attributo non funzionerà se il modulo viene creato utilizzando form_tag. L'unico modo per farlo funzionare è passare form_fore utilizzare f.submit formaction: 'your_path'.
fgblomqvist,


27

Questo è estremamente facile da testare

<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>

Inseriscilo in una pagina HTML, fai clic sui pulsanti e osserva l'URL


5
L'uso di GET qui è una pratica piuttosto negativa, si dovrebbe usare POST quando possibile.
Syncrossus,

6
@Syncrossus È a scopo di test.
Etienne Martin,

22

Usa l' formactionattributo HTML (5a riga):

<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>

2
Questo è simile alla precedente risposta di Leo .
ToolmakerSteve

@ToolmakerSteve - Ma gli utenti hanno votato . Fai la tua scelta!!
user12379095


11

Il modo migliore per gestire il pulsante di invio multiplo è utilizzare il caso switch nello script del server

<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>

codice server / script server - a cui si sta inviando il modulo:

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;
}

?>

Fonte: W3Schools.com


sì, è necessario avere un'idea degli script di azione (tecnologia di scripting lato server) È possibile utilizzare qualsiasi script / file per elaborare i dati inviati, ad esempio php, asp, jsp, ecc. <form action="demo_form.php" method="get">
Shailesh Sonare,

Va bene. Ciò era confuso perché esiste anche un linguaggio chiamato ActionScript. Dovresti invece dire "codice server" o "script server".
Civile,

Non avevo idea che potessi farlo con i pulsanti
William Isted,

10

Forse le soluzioni suggerite qui hanno funzionato nel 2009, ma ho testato tutte queste risposte avanzate e nessuno sta lavorando su alcun browser.

l'unica soluzione che ho trovato funzionante è questa: (ma penso che sia un po 'brutta da usare)

<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
Perché non usare solo formaction="actionurl1"? Non hai bisogno di JavaScript.
Rybo111,

3
@ rybo111 IE9 browser (la strega è relativamente ancora ampiamente utilizzata) non supportaformaction
clueless007

1
@inaliaghle Vero, è circa l'1% degli utenti - dipende da chi è rivolto il progetto. Circa l'1% degli utenti non utilizza JavaScript.
Rybo111,

1
Per i futuri lettori: non c'è niente di sbagliato nell'usare javascript, come in questa risposta. È un'abilità utile da sapere. OTOH, anche le risposte più votate funzionano bene - ignora la frase principale di questa risposta. Se per qualche motivo non riesci a far funzionare quelle altre risposte, pubblica il tuo codice completo come una domanda SO, spiega cosa succede (o non succede) e chiedi che cosa stai facendo di sbagliato.
ToolmakerSteve

6

Definisci namecome 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>

Esempio di codice server (PHP):

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

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

elseifmolto importante, perché entrambi verranno analizzati in caso contrario. Godere.


Ora questo è un suggerimento eccellente - principalmente perché puoi aggiungere più pulsanti con più casi molto facilmente e usare a switchcon un'azione predefinita se uno ha aggiunto un pulsante e ha dimenticato di aggiungerlo al switch(e / o errato qualcosa ecc.)
Gwyneth Llewelyn il

Inoltre, @Pato ha aggiunto una risposta simile che è probabilmente più idiomatica, ma la tua funziona bene!
Gwyneth Llewelyn,

1
@GwynethLlewelyn Non ho visto l'altra risposta o non ho notato quando ho scritto la mia. In realtà è lo stesso, ma questo sottolinea semplicemente come la maggior parte delle persone preferisce questa logica. La differenza è solo con i nomi per motivi semantici, una buona comprensione per i principianti o per chi ama iniziare con esso.
Thielicious

5

Dato che non hai specificato quale metodo di scripting lato server stai usando, ti darò un esempio che funziona per Python, usando CherryPy (anche se può essere utile anche per altri contesti):

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

Anziché utilizzare il valore per determinare quale pulsante è stato premuto, è possibile utilizzare il nome (con il <button>tag anziché <input>). In questo modo, se i tuoi pulsanti hanno lo stesso testo, non causeranno problemi. I nomi di tutti gli elementi del modulo, inclusi i pulsanti, vengono inviati come parte dell'URL. In CherryPy, ognuno di questi è un argomento per un metodo che esegue il codice lato server. Quindi, se il tuo metodo ha solo **kwargsper il suo elenco di parametri (invece di scrivere noiosamente ogni singolo nome di ogni elemento del modulo), puoi controllare per vedere quale pulsante è stato premuto in questo modo:

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

Penso che dovresti essere in grado di leggere il nome / valore nel tuo array GET. Penso che il pulsante a cui non è stato fatto clic non verrà visualizzato nell'elenco.


Molto probabilmente intendi l'array POST.
ypnos,

3
Non necessariamente, se il metodo del modulo è "POST", non verrà visualizzato nell'array GET. La maggior parte dei moduli viene inviata tramite POST.
Pappagalli,

2
O / o è tecnicamente giusto, eppure così sbagliato. Puoi inviare un modulo con method = "GET", ma è importante.
Bill the Lizard,

4
È solo "degno di nota" se usato in modo inappropriato: w3.org/2001/tag/doc/whenToUseGet.html .
mercatore,

2
Sì, non stavo cercando di suggerire GET, stavo solo cercando di generalizzare le cose.
John Bubriski

1

Puoi anche farlo in questo modo (penso che sia molto conveniente se hai N ingressi).

<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 caso d'uso comune sarebbe utilizzare ID diversi da un database per ciascun pulsante, in modo da poterlo sapere in seguito nel server su cui è stata cliccata la riga.

Nel lato server (PHP in questo esempio) puoi leggere "row" come un array per ottenere l'id. $_POST['row']sarà un array con un solo elemento, nel modulo [ id => value ](ad esempio:[ '123' => 'something' ] .

Quindi, per ottenere l'ID cliccato, fai:

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

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


Questo è simile alla risposta pubblicata da @Thielicious , ma la tua è probabilmente più idiomatica. Personalmente preferisco usare i tag alfanumerici per l'indice (rispetto ai numeri) per la leggibilità (più facile da ricordare cosa dovrebbe fare ogni pulsante), ma YMMV. Ma approfittare $_POST['row']dell'essere un array associativo è intelligente!
Gwyneth Llewelyn,

1
Sono d'accordo che, se hai a che fare con pulsanti statici, dovresti usare le chiavi con nome. Ma in alcuni casi non puoi. A volte si generano questi input in modo dinamico. Il caso più comune di questo sarebbe un elenco di righe, ognuna identificata da un ID. Immagino che stavo pensando a quel caso quando ho scritto la risposta (4 anni fa!). L'ho modificato, quindi è più ovvio che il numero è un ID e non un indice.
Pato

Molto bene! Sì, sono d'accordo, ora è più ovvio; Credo ancora che la tua risposta sia leggermente migliore di quella di @Thielicious (e forse anche un po 'più efficiente, specialmente se ci sono molti pulsanti).
Gwyneth Llewelyn,

1

Formulazione per più pulsanti di invio in un esempio di modulo

 <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

Semplice è possibile modificare l'azione del modulo su diversi pulsanti di invio Fare clic.

Prova questo nel documento

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

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

0

È inoltre possibile utilizzare un attributo href e inviare un get con il valore aggiunto per ciascun pulsante. Ma il modulo non sarebbe richiesto allora

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

Ciò non funzionerebbe per i controller in POSTrotta.
Xavi Montero,

quindi, "invia un get"
Jonathan Laliberte

3
Mi dispiace non essere d'accordo, ma GETnon è sempre adatto. Se "modifichi lo stato del tuo modello", non dovresti mai usare a GET, poiché l'aggiornamento del browser potrebbe comportare l'invio trasparente di due volte la stessa richiesta. Utilizzare GETsolo per "visualizzare" le cose e POSTper inviare richieste di cambiamenti di stato (aggiungere, rimuovere, modificare, ecc.). quindi POSTnell'azione del tuo controller altera lo stato (database, sessione ...) e lancia una risposta di reindirizzamento che quindi GETè il nuovo stato alterato. Fare GETper l'alterazione dello stato del modello è molto sporco e qualsiasi buon programmatore dovrebbe evitarlo. Mi dispiace dirlo. Clean code rulez.
Xavi Montero,

Vero. Ma a volte giocare sporco può essere pulito. Dipende da cosa stai facendo esattamente. Personalmente non mapperebbe le richieste di eliminazione e modifica su get, ma ci sono modi per farlo funzionare .. come controllare se è già stato eliminato, o se l'utente ha il permesso di farlo ecc ...
Jonathan Laliberte

-1

Puoi presentare i pulsanti in questo modo:

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

E poi nel codice puoi ottenere il valore usando:

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

(valUnits e valPrice sono alcuni altri valori che estraggo dal modulo che ho lasciato per l'illustrazione)


-1

Dal momento che non hai specificato quale metodo di scripting lato server stai usando, ti darò un esempio che funziona per 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>

Le forme

Quando fai clic su Accedi -> loginForm

Quando fai clic su Salva -> saveForm

Quando fai clic su Registra -> registrationForm

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.