Vários botões de envio em um formulário HTML

263

Digamos que você crie um assistente em um formulário HTML. Um botão volta e outro avança. Como o botão voltar aparece primeiro na marcação quando você pressiona Enter, ele usará esse botão para enviar o formulário.

Exemplo:

<form>
  <!-- Put your cursor in this field and press Enter -->
  <input type="text" name="field1" />

  <!-- This is the button that will submit -->
  <input type="submit" name="prev" value="Previous Page" />

  <!-- But this is the button that I WANT to submit -->
  <input type="submit" name="next" value="Next Page" />
</form>

Gostaria de decidir qual botão é usado para enviar o formulário quando um usuário pressiona Enter. Dessa forma, quando você pressionar Entero assistente, passará para a próxima página, não a anterior. Você precisa usar tabindexpara fazer isso?

Kevin
fonte

Respostas:

142

Eu espero que isso ajude. Estou apenas fazendo o truque de floatpressionar os botões à direita.

Dessa forma, o Prevbotão fica à esquerda do Nextbotão, mas o Nextprimeiro na estrutura HTML:

.f {
  float: right;
}
.clr {
  clear: both;
}
<form action="action" method="get">
  <input type="text" name="abc">
  <div id="buttons">
    <input type="submit" class="f" name="next" value="Next">
    <input type="submit" class="f" name="prev" value="Prev">
    <div class="clr"></div><!-- This div prevents later elements from floating with the buttons. Keeps them 'inside' div#buttons -->
  </div>
</form>

Benefícios em relação a outras sugestões: nenhum código JavaScript, acessível e os dois botões permanecem type="submit".

palotasb
fonte
23
Por favor, não faça isso sem também alterar a ordem das guias, para que pressionar o botão da guia alterne entre os botões conforme eles aparecem na tela.
11408 Steve Steve
61

Mude o tipo de botão anterior para um botão como este:

<input type="button" name="prev" value="Previous Page" />

Agora, o botão Avançar seria o padrão, além disso, você também poderá adicionar o defaultatributo a ele, para que seu navegador o destaque assim:

<input type="submit" name="next" value="Next Page" default />
Wally Lawless
fonte
39
De que defaultatributo você está falando? Não existe um atributo "padrão", que seria válido: w3.org/html/wg/drafts/html/master/… (não no HTML5, HTML 4.01 Transitório / Estrito, XHTML 1.0 Estrito). E não vejo por que mudar o tipo de entrada de submitpara buttonseria melhor. Você pode ter vários elementos de entrada do tipo de envio em um formulário sem problemas. Eu realmente não entendo por que essa resposta é tão votada.
Sk8erPeter
3
Ter uma entrada do tipo "botão" não executa a ação do formulário. Você pode ter um onclick ou algo assim, executando, assim, outra função que não seja a ação do formulário "padrão" (que é executada pressionando o botão do tipo "enviar"). Era isso que eu estava procurando e foi por isso que votei na votação. Não posso falar pelo atributo "padrão", não fazia parte do meu problema;) obrigado pelo seu esclarecimento.
Jonas
2
@ Sk8erPeter, @Jonas .... hmm .. Suspeito que este defaultatributo seja um atributo Global; atributo enumerado .. que está relacionado aos estados de enumeração: w3.org/html/wg/drafts/html/master/… . além desse ponto .. o aspecto do botão desta resposta não é uma resposta .. é uma " sugestão condicional " ou uma consulta ( própria pergunta ).
Brett Caswell
3
@ Jonas: sim, type="button"não envia o formulário, envia type="submit", mas alterar o tipo desses botões definitivamente não é uma solução, porque esses botões devem se comportar basicamente da mesma maneira - a questão do OP era como fazer com que o botão "Avançar" padrão para pressionar a tecla Enter. E há uma solução possível na resposta aceita.
precisa saber é o seguinte
4
@BrettCaswell: alterar o tipo desses botões é uma solução alternativa ruim (veja meu comentário anterior). Não há defaultatributo válido para inputtags (como afirmei anteriormente) em HTML, e os navegadores (populares) NÃO destacarão o botão que possui esse atributo, o que significa que não há implementação fora do padrão desse atributo - então ainda não sei sobre o que @Wally Lawless estava falando e por que essa resposta é superestimada. Existe apenas um defaultatributo válido introduzido no HTML5, MAS apenas para a <track>tag: developer.mozilla.org/en-US/docs/Web/HTML/Element/track
Sk8erPeter
56

Dê aos seus botões de envio o mesmo nome:

<input type="submit" name="submitButton" value="Previous Page" />
<input type="submit" name="submitButton" value="Next Page" />

Quando o usuário pressiona Entere a solicitação vai para o servidor, você pode verificar o valor submitButtonno código do servidor que contém uma coleção de name/valuepares de formulários . Por exemplo, no ASP Classic :

If Request.Form("submitButton") = "Previous Page" Then
    ' Code for the previous page
ElseIf Request.Form("submitButton") = "Next Page" Then
    ' Code for the next page
End If

Referência: usando vários botões de envio em um único formulário

huseyint
fonte
26
Não é isso que o usuário pediu. O usuário queria saber como controlar qual botão de envio em um formulário é ativado quando a tecla Enter é pressionada, ou seja. qual é o botão padrão.
6139 kosoant
20
não funciona em um aplicativo I18n em que você nem conhece o rótulo do botão.
31510 Chris
Em que solução de sistema ou tecnologia o próprio servidor não saberia qual o rótulo usado para o botão seguinte e voltar? O servidor não gerou o botão Avançar e Voltar em primeiro lugar? (Se a localização é tratado no lado do cliente, imagino o servidor pode não saber, mas eu nunca ter ouvido falar deste para HTML)
Jacob
Essa resposta erra completamente a pergunta, provavelmente é para uma pergunta diferente. Por que tantos votos positivos ?? Sem mencionar que nunca se deve verificar o rótulo do botão ... exige muitos problemas. Mesmo o caso simples: "devemos abreviar a string para 'Página anterior'" arruinará a funcionalidade do seu site.
Tylla
30

Se o fato de o primeiro botão ser usado por padrão for consistente entre os navegadores, coloque-os da maneira certa no código-fonte e use CSS para mudar de posição aparente.

float esquerda e direita para trocá-las visualmente, por exemplo.

Polsonby
fonte
18

Às vezes, a solução fornecida pelo @palotasb não é suficiente. Há casos de uso em que, por exemplo, um botão "Filtro" envia é colocado acima dos botões como "Próximo e Anterior". Encontrei uma solução alternativa para isso: copie o botão de envio, que precisa atuar como o botão de envio padrão em uma div oculta, e coloque-o dentro do formulário acima de qualquer outro botão de envio. Tecnicamente, ele será enviado por um botão diferente ao pressionar Enter e ao clicar no botão Avançar visível. Mas como o nome e o valor são iguais, não há diferença no resultado.

<html>
<head>
    <style>
        div.defaultsubmitbutton {
            display: none;
        }
    </style>
</head>
<body>
    <form action="action" method="get">
        <div class="defaultsubmitbutton">
            <input type="submit" name="next" value="Next">
        </div>
        <p><input type="text" name="filter"><input type="submit" value="Filter"></p>
        <p>Filtered results</p>
        <input type="radio" name="choice" value="1">Filtered result 1
        <input type="radio" name="choice" value="2">Filtered result 2
        <input type="radio" name="choice" value="3">Filtered result 3
        <div>                
            <input type="submit" name="prev" value="Prev">
            <input type="submit" name="next" value="Next">
        </div>
    </form>
</body>
</html>
netiul
fonte
17

Eu usaria JavaScript para enviar o formulário. A função seria acionada pelo evento OnKeyPress do elemento do formulário e detectaria se oEnter chave foi selecionada. Se for esse o caso, ele enviará o formulário.

Aqui estão duas páginas que fornecem técnicas sobre como fazer isso: 1 , 2 . Com base nesses, aqui está um exemplo de uso (com base aqui ):

<SCRIPT TYPE="text/javascript">//<!--
function submitenter(myfield,e) {
  var keycode;
  if (window.event) {
    keycode = window.event.keyCode;
  } else if (e) {
    keycode = e.which;
  } else {
    return true;
  }

  if (keycode == 13) {
    myfield.form.submit();
    return false;
  } else {
    return true;
  }
}
//--></SCRIPT>

<INPUT NAME="MyText" TYPE="Text" onKeyPress="return submitenter(this,event)" />
Yaakov Ellis
fonte
2
O que acontece se o javascript estiver desativado?
11139 Jon Winstanley
2
Você não deve usar <! - e -> para comentar JS, essas marcas não são símbolos linguagem Javascript
Marecky
2
@ Marecky Eles não devem comentar JS. Eles são ignorados ao analisar o conteúdo de <script> em um navegador que suporta <script>. Hoje eles realmente não são necessários. Mas em navegadores muito antigos, esse era um truque de compatibilidade para evitar que o script fosse impresso como texto simples.
Leem
17

Se você realmente deseja que ele funcione como uma caixa de diálogo de instalação, basta focar no botão "Avançar" do OnLoad.

Dessa forma, se o usuário Returnclicar, o formulário será enviado e seguirá em frente. Se eles quiserem voltar, podem clicar Tabou clicar no botão.

Scott Gottreu
fonte
2
Eles significam que alguém preenche um formulário e clica em Return enquanto estiver em um campo de texto.
Jordan Reiter
17

Isso não pode ser feito com HTML puro. Você deve confiar no JavaScript para esse truque.

No entanto, se você colocar dois formulários na página HTML, poderá fazer isso.

Formulário1 teria o botão anterior.

O Form2 teria qualquer entrada do usuário + o próximo botão.

Quando o usuário pressiona Enterno Form2, o botão Próximo enviar será acionado.

FlySwat
fonte
16

Você pode fazer isso com CSS.

Coloque os botões na marcação com o Nextbotão primeiro, depois o Prevbotão depois.

Em seguida, use CSS para posicioná-los da maneira que você deseja.

qui
fonte
14

Isso funciona sem JavaScript ou CSS na maioria dos navegadores:

<form>
    <p><input type="text" name="field1" /></p>
    <p><a href="previous.html">
    <button type="button">Previous Page</button></a>
    <button type="submit">Next Page</button></p>
</form>

Firefox, Opera, Safari e Google Chrome funcionam.
Como sempre, o Internet Explorer é o problema.

Esta versão funciona quando o JavaScript está ativado:

<form>
    <p><input type="text" name="field1" /></p>
    <p><a href="previous.html">
    <button type="button" onclick="window.location='previous.html'">Previous Page</button></a>
    <button type="submit">Next Page</button></p>
</form>

Portanto, a falha nesta solução é:

A Página anterior não funcionará se você usar o Internet Explorer com JavaScript desativado.

Lembre-se, o botão Voltar ainda funciona!

Jolyon
fonte
1
Sem javascript, você não poderá ativar o botão "página anterior", porque o tipo = "botão"!
Risco #
O problema com sua sugestão é que um botão type = "button" não publicaria o formulário, portanto, basicamente não faz nada, enquanto a segunda versão com uma âncora criaria um GET em vez de um POST.
Tylla
12

Se você tiver vários botões ativos em uma página, poderá fazer algo assim:

Marque o primeiro botão que você deseja acionar no Enterpressionamento de tecla como o botão padrão no formulário. Para o segundo botão, associe-o ao Backspacebotão do teclado. O Backspacecódigo do evento é 8.

$(document).on("keydown", function(event) {
  if (event.which.toString() == "8") {
    var findActiveElementsClosestForm = $(document.activeElement).closest("form");

    if (findActiveElementsClosestForm && findActiveElementsClosestForm.length) {
      $("form#" + findActiveElementsClosestForm[0].id + " .secondary_button").trigger("click");
    }
  }
});
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>

<form action="action" method="get" defaultbutton="TriggerOnEnter">
  <input type="submit" id="PreviousButton" name="prev" value="Prev" class="secondary_button" />
  <input type="submit" id='TriggerOnEnter' name="next" value="Next" class="primary_button" />
</form>

user1591131
fonte
11

Alterar a ordem das guias deve ser o suficiente para fazer isso. Mantenha simples.

Outra opção simples seria colocar o botão voltar após o botão enviar no código HTML, mas flutuar para a esquerda para que apareça na página antes do botão enviar.

Kenny Johnson
fonte
10
<input type="submit" name="perv" value="Previous Page"> 
<input type="submit" name="prev" value="Next Page"> 

Mantenha o nome de todos os botões de envio iguais - "anterior".

A única diferença é a value atributo com valores exclusivos. Quando criamos o script, esses valores exclusivos nos ajudarão a descobrir qual dos botões de envio foi pressionado.

E escreva a seguinte codificação:

    btnID = ""
if Request.Form("prev") = "Previous Page" then
    btnID = "1"
else if Request.Form("prev") = "Next Page" then
    btnID = "2"
end if
jayu
fonte
O problema é que pressionar Enter em um campo de texto enviará o formulário com o primeiro botão de envio, não com o pretendido (segundo no exemplo). Descobrir qual botão de envio foi usado para enviar o formulário é fácil, e essa não foi a pergunta!
riskop
Por que name="perv"?
Peter Mortensen
10

Outra opção simples seria colocar o botão voltar após o botão enviar no código HTML, mas flutuar para a esquerda, para que apareça na página antes do botão enviar.

Alterar a ordem das guias deve ser o suficiente para fazer isso. Mantenha simples.

Peter Mortensen
fonte
10

A primeira vez que me deparei com isso, criei um hack onclick () / JavaScript quando as opções não são anteriores / próximas das quais ainda gosto por sua simplicidade. É assim:

@model myApp.Models.myModel

<script type="text/javascript">
    function doOperation(op) {
        document.getElementById("OperationId").innerText = op;
        // you could also use Ajax to reference the element.
    }
</script>

<form>
  <input type="text" id = "TextFieldId" name="TextField" value="" />
  <input type="hidden" id="OperationId" name="Operation" value="" />
  <input type="submit" name="write" value="Write" onclick='doOperation("Write")'/>
  <input type="submit" name="read" value="Read" onclick='doOperation("Read")'/>
</form>

Quando um dos botões de envio é clicado, ele armazena a operação desejada em um campo oculto (que é um campo de string incluído no modelo ao qual o formulário está associado) e envia o formulário ao Controlador, que decide tudo. No Controller, você simplesmente escreve:

// Do operation according to which submit button was clicked
// based on the contents of the hidden Operation field.
if (myModel.Operation == "Read")
{
     // Do read logic
}
else if (myModel.Operation == "Write")
{
     // Do write logic
}
else
{
     // Do error logic
}

Você também pode aumentar um pouco isso usando códigos de operação numéricos para evitar a análise de string, mas, a menos que você jogue com enumerações, o código é menos legível, modificável e auto-documentável, e a análise é trivial, de qualquer maneira.

MiddleAgedMutantNinjaProgrammer
fonte
9

De https://html.spec.whatwg.org/multipage/forms.html#implicit-submission

O botão padrão de um elemento do formulário é o primeiro botão de envio em ordem de árvore cujo proprietário do formulário é esse elemento do formulário.

Se o agente do usuário oferecer suporte para permitir que o usuário envie um formulário implicitamente (por exemplo, em algumas plataformas, pressione a tecla "enter" enquanto um campo de texto estiver focado no envio implícito do formulário) ...

Tendo a próxima entrada como type = "submit" e alterando a entrada anterior para type = "button" deve fornecer o comportamento padrão desejado.

<form>
   <input type="text" name="field1" /> <!-- put your cursor in this field and press Enter -->

   <input type="button" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
   <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>
nikkypx
fonte
9

Isto é o que eu tentei:

  1. Você precisa ter nomes diferentes para seus botões
  2. Escreva uma ifdeclaração que fará a ação necessária se um dos botões for clicado.

 

<form>
    <input type="text" name="field1" /> <!-- Put your cursor in this field and press Enter -->

    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

No PHP,

if(isset($_POST['prev']))
{
    header("Location: previous.html");
    die();
}

if(isset($_POST['next']))
{
    header("Location: next.html");
    die();
}
Samuel Mugisha
fonte
O problema é que pressionar Enter em um campo de texto enviará o formulário com o primeiro botão de envio, não com o pretendido (segundo no exemplo). Descobrir qual botão de envio foi usado para enviar o formulário é fácil, e essa não foi a pergunta!
riskop
7

Me deparei com essa pergunta ao tentar encontrar uma resposta basicamente para a mesma coisa, apenas com os controles do ASP.NET, quando descobri que o botão ASP possui uma propriedade chamada UseSubmitBehaviorque permite definir qual deles é enviado.

<asp:Button runat="server" ID="SumbitButton" UseSubmitBehavior="False" Text="Submit" />

Apenas no caso de alguém estar procurando o botão ASP.NET para fazer isso.

Barry Franklin
fonte
6

Com o JavaScript (aqui jQuery), você pode desativar o botão anterior antes de enviar o formulário.

$('form').on('keypress', function(event) {
    if (event.which == 13) {
        $('input[name="prev"]').prop('type', 'button');
    }
});
GuillaumeS
fonte
1

Tente isso ..!

<form>
  <input type="text" name="Name" />
  <!-- Enter the value -->

  <input type="button" name="prev" value="Previous Page" />
  <!-- This is the button that will submit -->
  <input type="submit" name="next" value="Next Page" />
  <!-- But this is the button that I WANT to submit -->
</form>

Gowtham Balusamy
fonte
1

Eu resolvi um problema muito semelhante desta maneira:

  1. Se o JavaScript estiver ativado (na maioria dos casos atualmente), todos os botões de envio serão " degradados " para os botões no carregamento da página via JavaScript (jQuery). Os eventos de clique no botão " degradado " são digitados também em JavaScript.

  2. Se o JavaScript não estiver ativado, o formulário será exibido no navegador com vários botões de envio. Nesse caso, pressionar Enterum textfielddentro do formulário enviará o formulário com o primeiro botão em vez do padrão pretendido , mas pelo menos o formulário ainda poderá ser utilizado: você pode enviar com os botões anterior e próximo .

Exemplo de trabalho:

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    </head>

    <body>
        <form action="http://httpbin.org/post" method="post">
            If JavaScript  is disabled, then you CAN submit the form
            with button1, button2 or button3.

            If you press enter on a text field, then the form is
            submitted with the first submit button.

            If JavaScript is enabled, then the submit typed buttons
            without the 'defaultSubmitButton' style are converted
            to button typed buttons.

            If you press Enter on a text field, then the form is
            submitted with the only submit button
            (the one with class defaultSubmitButton)

            If you click on any other button in the form, then the
            form is submitted with that button's value.

            <br />

            <input type="text" name="text1" ></input>
            <button type="submit" name="action" value="button1" >button 1</button>
            <br />

            <input type="text" name="text2" ></input>
            <button type="submit" name="action" value="button2" >button 2</button>
            <br />

            <input type="text" name="text3" ></input>
            <button class="defaultSubmitButton" type="submit" name="action" value="button3" >default button</button>
        </form>

        <script>
            $(document).ready(function(){

                /* Change submit typed buttons without the 'defaultSubmitButton'
                   style to button typed buttons */
                $('form button[type=submit]').not('.defaultSubmitButton').each(function(){
                    $(this).attr('type', 'button');
                });

                /* Clicking on button typed buttons results in:
                   1. Setting the form's submit button's value to
                      the clicked button's value,
                   2. Clicking on the form's submit button */
                $('form button[type=button]').click(function( event ){
                    var form = event.target.closest('form');
                    var submit = $("button[type='submit']",form).first();
                    submit.val(event.target.value);
                    submit.click();
                });
            });
        </script>
    </body>
</html>

riskop
fonte
0

Você pode usar Tabindexpara resolver esse problema. Também alterar a ordem dos botões seria uma maneira mais eficiente de conseguir isso.

Altere a ordem dos botões e adicione floatvalores para atribuir a eles a posição desejada que você deseja mostrar em sua HTMLexibição.

Jyoti mishra
fonte
-4

Usando o exemplo que você deu:

<form>
    <input type="text" name="field1" /><!-- Put your cursor in this field and press Enter -->
    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

Se você clicar em "Página anterior", apenas o valor de "anterior" será enviado. Se você clicar em "Próxima página", apenas o valor de "próxima" será enviado.

Se, no entanto, você pressionar Enter algum lugar do formulário, nem "prev" nem "next" serão enviados.

Portanto, usando o pseudocódigo, você pode fazer o seguinte:

If "prev" submitted then
    Previous Page was click
Else If "next" submitted then
    Next Page was click
Else
    No button was click
GateKiller
fonte
1
Nunca há uma situação (sem usar js) em que nenhum dos botões é acionado. Se você pressionar ENTER, o primeiro botão no código capturará o evento. No exemplo html, é o botão anterior.
amigos estão dizendo sobre simone