Dois botões de envio em um formulário


534

Eu tenho dois botões de envio em um formulário. Como determinar qual foi atingido no servidor?


Considere alterar a resposta aceita para a resposta dos papagaios .
Peter Mortensen

2
@ PeterMortensen - Nem a resposta aceita nem a resposta do Parrot são as melhores hoje. Veja a resposta de Leo para a solução HTML5 mais recente usando o atributo formaction. Ou veja a resposta de kiril para saber como tornar o HTML visível ao usuário independente do valor enviado ao navegador - resolvendo o problema da internacionalização de maneira mais fácil de codificar do que a resposta de Greg ou Parrot.
Página

Respostas:


448

Se você der um nome a cada um, o clique será enviado como qualquer outra entrada.

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

101
Verifique também se o nome do botão tem o nome correto! Por exemplo, "botão-1" NÃO funcionaria. Pode poupar muitos aborrecimentos, por isso lembre-se disso.
Pdolinaj

22
Normalmente, todas as entradas no formulário são enviadas com o formulário. Como o valor de um botão é enviado apenas se clicado, você precisa procurar nos valores do formulário esses nomes predefinidos. Acho que a outra resposta ( stackoverflow.com/a/21778226/88409 ) que envolve dar a todos o mesmo nome, com valores diferentes, faz mais sentido. Depois, basta pegar o valor com um único nome de campo de formulário conhecido. Também torna mais óbvio que apenas um valor (o clicado) será enviado para o nome de entrada especificado, assim como os botões de opção funcionam (mesmo nome, valores diferentes).
Triynko

6
@Triynko, como Robin Green disse nos comentários dessa resposta, essa é melhor para a internacionalização. Por exemplo, se a página for renderizada em espanhol, o texto dos botões provavelmente será diferente. Portanto, ter a lógica do seu código depende do texto desse botão será interrompido nesse caso. Indicar pelo nome é mais seguro, pois é um valor que não é exibido ao usuário e, portanto, pode ser tratado mais como uma variável "particular" e menos como uma mensagem para os usuários.
precisa saber é o seguinte

Para esclarecer o comentário de @ sfarbota: A primeira solução mostrada na resposta do Parrot é problemática, pois se baseia em testar o valor visível ao usuário . Isso é duvidoso - o código que quebra ao alterar uma palavra visível ao usuário é considerado "frágil". A segunda solução mostrada na resposta do Parrot é boa - é a mesma que esta. A segunda solução do Parrot também mostra o código correspondente a ser escrito, portanto, é uma resposta mais útil que esta.
Home

2
Veja a resposta de Leo para a solução HTML5 mais recente usando o atributo formaction. Ou veja a resposta de kiril para saber como tornar o HTML visível ao usuário independente do valor enviado ao navegador - resolvendo o problema da internacionalização.
Home

875

Solução 1:
Atribua a cada entrada um valor diferente e mantenha o mesmo nome:

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

Em seguida, verifique o código para ver qual foi acionado:

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

O problema é que você vincula sua lógica ao texto visível do usuário na entrada.


Solução 2:
Atribua a cada um um nome exclusivo e verifique o $ _POST quanto à existência dessa entrada:

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

E no código:

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

37
Para fins do i18n, talvez seja melhor usar a resposta selecionada.
Robin Green

11
@LaszloPapp como a própria resposta diz, se você usar a resposta selecionada acima, poderá internacionalizar o formulário (por exemplo, traduzir para diferentes idiomas ou dialetos) sem afetar a lógica. Se você usar a primeira opção nesta resposta, a lógica dependerá do idioma em que o formulário é realmente apresentado.
Robin Green

1
@RobinGreen: Acho que a maioria das pessoas usará a segunda lógica, não é?
lpapp

5
i18n = i [nternationalizatio] n, e os 18 representam as 18 letras entre a primeira e a última.
Buttle Butkus

18
O OP não pediu PHP.
Rudey

110

Uma solução ainda melhor consiste em usar tags de botão para enviar o formulário:

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

O HTML dentro do botão (por exemplo, ..>Update<..é o que é visto pelo usuário; porque há HTML fornecido, ovalue não é visível ao usuário; ele é enviado apenas ao servidor. Dessa forma, não há inconvenientes com a internacionalização e vários idiomas de exibição (no solução anterior, o rótulo do botão também é o valor enviado ao servidor).


13
Aparentemente, o comportamento do navegador difere; alguns enviam o atributo value, outros a string entre as tags ... Portanto, tenha cuidado com este.
Jeroen Dierckx

1
Eu acho que o trecho fornecidas são totalmente suportados ( w3schools.com/tags/att_button_type.asp )
Kiril

2
@kiril o trecho desse link usa dois tipos diferentes de <button>: submite reset. Observe que resetnão envia nada, apenas redefine o formulário. Portanto, o argumento de Jeroen permanece.
Fizluk

7
Ok, você está certo. Depois, verifiquei o rascunho de trabalho do HTML5 W3C. Citação: >> O atributo value fornece o valor do elemento para fins de envio do formulário. O valor do elemento é o valor do atributo value do elemento, se houver um, ou a sequência vazia, caso contrário. >> NOTA: Um botão (e seu valor) só será incluído no envio do formulário se o próprio botão foi usado para iniciar o envio do formulário.
Kiril

8
@Jeroen Bull. Quais navegadores enviam o texto entre as tags? Uma entrada ou botão só deve enviar o atributo 'value'. Um botão pode literalmente ter qualquer coisa entre as tags, incluindo imagens ou outras tags HTML. Esse é o objetivo de usar um botão sobre um elemento de entrada e você está tentando sugerir que o navegador despeje todo esse conteúdo como valor? De jeito nenhum.
Triynko 10/11

93

Há uma nova abordagem HTML5 para isso, o formactionatributo:

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

Aparentemente, isso não funciona no IE9 e versões anteriores, mas para outros navegadores você deve estar bem (consulte: w3schools.com <button> formatação HTML ).

Pessoalmente, geralmente uso o Javascript para enviar formulários remotamente (para um feedback percebido mais rápido) com essa abordagem como backup. Entre os dois, as únicas pessoas não cobertas são o IE <9 com Javascript desativado.

Obviamente, isso pode ser inapropriado se você estiver basicamente executando a mesma ação no lado do servidor, independentemente de qual botão foi pressionado, mas geralmente se houver duas ações no lado do usuário disponíveis, elas também serão mapeadas para duas ações no lado do servidor.

Editar: Conforme observado por Pascal_dher nos comentários, esse atributo também está disponível na <input>tag também.


1
Também disponível para a tag "input". Accoding w3schools: ao usar tag botão diferentes navegadores podem apresentar valores diferentes: w3schools.com/tags/tag_button.asp
Pascal_dher

3
Sou desenvolvedor web há 12 anos e este é novo para mim e era exatamente o que eu precisava, na verdade. Obrigado!
precisa saber é o seguinte

1
De nada @KyleFarris! Eu acredito que isso só se tornou possível relativamente recentemente, então não é surpresa se você ainda não se deparou com isso.
Leo

2
Nota para usuários do Rails: adicionar este atributo não funcionará se seu formulário for criado usando form_tag. A única maneira de fazê-lo funcionar é mudar form_fore usar f.submit formaction: 'your_path'.
precisa saber é o seguinte


27

Isso é extremamente fácil de testar

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

Coloque isso em uma página HTML, clique nos botões e veja o URL


5
Usar GET aqui é uma prática um tanto ruim, deve-se usar o POST quando possível.
Syncrossus 28/05

6
@ Syncrossus Isso é para fins de teste.
Etienne Martin

22

Use o formactionatributo HTML (5ª linha):

<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
Isso é semelhante à resposta anterior de Leo .
Página

@ToolmakerSteve - Mas os usuários votaram positivamente . faça sua escolha!!
user12379095

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

Recurso HTML5. Funciona perfeitamente em navegadores recentes, obrigado!
Stephane Lallemagne

1
NOTA: Essa parece ser a mesma da resposta anterior de Leo , exceto que mostra o uso da inputetiqueta em vez da buttonetiqueta.
Página

11

A melhor maneira de lidar com vários botões de envio é usar maiúsculas e minúsculas no script do servidor

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

código do servidor / script do servidor - onde você está enviando o formulário:

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


sim, é que você deve ter uma idéia sobre scripts de ação (servidor de tecnologia de script lado) Você pode usar qualquer script / arquivo para processar dados enviados por exemplo, php, asp, jsp, etc. <form action="demo_form.php" method="get">
Shailesh Sonare

OK. Isso foi confuso porque também existe uma linguagem chamada ActionScript. Você deve dizer: "código do servidor" ou "script do servidor".
Civil

Eu não tinha idéia que você poderia fazer isso com botões
William isTed

10

Talvez as soluções sugeridas aqui tenham funcionado em 2009, mas eu testei todas essas respostas aprovadas e ninguém está trabalhando em nenhum navegador.

única solução que eu encontrei trabalhando é esta: (mas é um pouco feio de usar, eu acho)

<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
Por que não usar apenas formaction="actionurl1"? Você não precisa de JavaScript.
Rybo111

3
@ rybo111 IE9 navegador (bruxa está relativamente parado amplamente utilizado) não suportaformaction
clueless007

1
@inaliaghle True, são cerca de 1% dos usuários - depende para quem o projeto é direcionado. Aproximadamente 1% dos usuários não usa JavaScript.
rybo111

1
Para futuros leitores: não há nada de errado em usar o javascript, como nesta resposta. É uma habilidade útil para saber. OTOH, as respostas mais votadas também funcionam bem - ignore a frase principal desta resposta. Se, por algum motivo, você não conseguir que essas outras respostas funcionem, publique seu código completo como uma pergunta SO, explique o que acontece (ou não) e pergunte o que está fazendo de errado.
Página

6

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

Exemplo de código do servidor (PHP):

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

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

elseifmuito importante, porque ambos serão analisados, se não. Aproveitar.


Agora, essa é uma excelente sugestão - principalmente porque você pode adicionar mais botões com mais casos com muita facilidade e usar um switchcom uma ação padrão se alguém tiver adicionado um botão e esquecido de adicioná-lo ao switch(e / ou escrever algo errado, etc.)
Gwyneth Llewelyn

Além disso, o @Pato adicionou uma resposta semelhante, possivelmente mais idiomática, mas a sua funciona bem!
Gwyneth Llewelyn

1
@GwynethLlewelyn Não vi a outra resposta de volta ou não percebi quando escrevi a minha. Na verdade, é o mesmo, mas isso simplesmente enfatiza como a maioria das pessoas prefere essa lógica. A diferença é apenas com nomes por razões semânticas, bom entendimento para novatos ou quem gosta de começar com ela.
Thielicious

5

Como você não especificou qual método de script do servidor você está usando, darei um exemplo que funciona para Python, usando CherryPy (embora possa ser útil também para outros contextos):

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

Em vez de usar o valor para determinar qual botão foi pressionado, você pode usar o nome (com a <button>tag em vez de <input>). Dessa forma, se seus botões tiverem o mesmo texto, isso não causará problemas. Os nomes de todos os itens de formulário, incluindo botões, são enviados como parte da URL. No CherryPy, cada um desses é um argumento para um método que executa o código do lado do servidor. Portanto, se o seu método tiver apenas uma **kwargslista de parâmetros (em vez de digitar tediosamente todos os nomes de cada item do formulário), verifique se o botão foi pressionado assim:

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

Eu acho que você deve ser capaz de ler o nome / valor em sua matriz GET. Acho que o botão que não foi clicado não aparecerá nessa lista.


Você provavelmente quer dizer a matriz POST.
ypnos

3
Não necessariamente, se o método do formulário for "POST", ele não aparecerá na matriz GET. A maioria dos formulários é enviada via POST.
papagaios

2
Ou / ou é tecnicamente certo e, no entanto, tão errado. Você pode enviar um formulário com o método = "GET", mas é digno de nota.
Bill o Lagarto

4
É apenas " digno de nota " quando usado de forma inadequada: w3.org/2001/tag/doc/whenToUseGet.html .
Mercator

2
Sim, eu não estava tentando sugerir GET, apenas tentando generalizar as coisas.
John Bubriski

1

Você também pode fazer assim (acho muito conveniente se você tiver N entradas).

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

Um caso de uso comum seria usar diferentes IDs de um banco de dados para cada botão, para que você possa saber mais tarde no servidor em que linha foi clicada.

No lado do servidor (PHP neste exemplo), você pode ler "row" como uma matriz para obter o ID. $_POST['row']será uma matriz com apenas um elemento, no formato [ id => value ](por exemplo [ '123' => 'something' ]:).

Portanto, para obter o ID clicado, você deve:

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

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


Isso é semelhante à resposta @ Thielicious postada , mas a sua é possivelmente mais idiomática. Pessoalmente, prefiro usar tags alfanuméricas para o índice (em oposição a números) para facilitar a leitura (mais fácil lembrar o que cada botão deve fazer), mas o YMMV. Mas tirar vantagem de $_POST['row']ser uma matriz associativa é inteligente!
Gwyneth Llewelyn

1
Concordo que, se você está lidando com botões estáticos, deve usar chaves nomeadas. Mas em alguns casos você não pode. Às vezes, você gera essas entradas dinamicamente. O caso mais comum disso seria uma lista de linhas, cada uma identificada por um ID. Acho que estava pensando nesse caso quando escrevi a resposta (há 4 anos!). Eu o editei para que fique mais óbvio que o número é um ID e não um índice.
Pato

Bem feito! Sim, eu concordo, é mais óbvio agora; Ainda acredito que sua resposta é marginalmente melhor que a de @Thielicious (e possivelmente até um pouco mais eficiente, especialmente se houver muitos botões).
Gwyneth Llewelyn

1

Você formata vários botões de envio em um exemplo de formulário

 <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

Simples, você pode alterar a ação do formulário em diferentes botões de envio Clique em.

Tente isso no documento.

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

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

0

Você também pode usar um atributo href e enviar um get com o valor acrescentado para cada botão. Mas o formulário não seria necessário então

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

Isso não funcionaria para controladores sob POSTrotas.
Xavi Montero

portanto, "envie um get"
Jonathan Laliberte 04/02

3
Lamento discordar, mas GETnem sempre é adequado. Se você "modificar o estado do seu modelo", nunca deverá usar a GET, pois a atualização do navegador pode resultar no envio transparente de duas vezes a mesma solicitação. Use GETapenas para "visualizar" as coisas e POSTenviar solicitações de alterações de estado (adicionar, remover, editar etc.). em seguida, na POSTação do seu controlador, altere o estado (banco de dados, sessão ...) e lance uma resposta de redirecionamento que será GETo novo estado alterado. Fazer GETalterações no estado do modelo é muito sujo e qualquer bom codificador deve evitá-lo. Desculpe dizer isso. Limpe o código rulez.
Xavi Montero

Verdade. Mas jogar sujo pode às vezes ser limpo. Depende do que você está fazendo exatamente. Pessoalmente, ele não mapeará as solicitações de exclusão e edição em um get, mas existem maneiras de fazê-lo funcionar. Como verificar se já foi excluído ou verificar se o usuário tem permissão para fazê-lo, etc ...
Jonathan Laliberte

-1

Você pode apresentar os botões assim:

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

E então, no código, você pode obter o valor usando:

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

(valUnits e valPrice são outros valores extraídos do formulário que deixei para ilustração)


-1

Como você não especificou qual método de script do lado do servidor está usando, darei um exemplo que funciona para 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>

Formulários

Quando clicar em Login -> loginForm

Quando clicar em Salvar -> saveForm

Quando clicar em Register -> registrationForm

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.