Se um formulário for enviado, mas não por um botão específico, como
- pressionando Enter
- usando
HTMLFormElement.submit()
em JS
como um navegador deve determinar qual dos vários botões de envio, se houver, usar como o pressionado?
Isso é significativo em dois níveis:
- chamando um
onclick
manipulador de eventos anexado a um botão de envio - os dados enviados de volta ao servidor da web
Minhas experiências até agora mostraram que:
- ao pressionar Enter, Firefox, Opera e Safari usam o primeiro botão de envio no formulário
- ao pressionar Enter, o IE usa o primeiro botão de envio ou nenhum, dependendo das condições que não consegui descobrir
- todos esses navegadores não usam nenhum para envio de JS
O que diz o padrão?
Se ajudar, aqui está o meu código de teste (o PHP é relevante apenas para o meu método de teste, não para a minha pergunta)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
<input type="text" name="method" />
<input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
<input type="text" name="stuff" />
<input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
<input type="button" value="submit" onclick="document.theForm.submit();" />
</form>
</body></html>
fonte
O HTML 4 não o torna explícito. O rascunho de trabalho atual do HTML5 especifica que o primeiro botão de envio deve ser o padrão :
fonte
O Andrezj praticamente conseguiu isso ... mas aqui está uma solução fácil para vários navegadores.
Tome uma forma como esta:
e refatorar para isso:
Como a especificação do W3C indica que vários botões de envio são válidos, mas omite orientações sobre como o agente do usuário deve lidar com eles, os fabricantes de navegadores são deixados de implementar como acharem melhor. Descobri que eles enviarão o primeiro botão de envio no formulário ou o próximo botão de envio após o campo do formulário atualmente em foco.
Infelizmente, basta adicionar um estilo de exibição: nenhum; não funcionará porque a especificação W3C indica que qualquer elemento oculto deve ser excluído das interações do usuário. Então, esconda-o à vista de todos!
Acima está um exemplo da solução que acabei colocando em produção. Pressionar a tecla Enter aciona o envio padrão do formulário como um comportamento esperado, mesmo quando outros valores não padrão estão presentes e precedem o botão de envio padrão no DOM. Bônus para interação mouse / teclado com entradas explícitas do usuário, evitando manipuladores javascript.
Nota: percorrer o formulário não exibirá o foco de nenhum elemento visual, mas fará com que o botão invisível seja selecionado. Para evitar esse problema, basta definir os atributos tabindex adequadamente e omitir um atributo tabindex no botão de envio invisível. Embora possa parecer incorreto promover esses estilos como importantes, eles devem impedir que qualquer estrutura ou estilo de botão existente interfira com essa correção. Além disso, esses estilos inline são definitivamente ruins, mas estamos provando conceitos aqui ... não escrevendo código de produção.
fonte
<div style="position: fixed; left: -1000px; top: -1000px />
. Só mais uma coisa a se preocupar: apenas minimizar ou afastar o botão do fluxo da página com CSS pode trazer problemas de WAI, porque os leitores de tela ainda verão o botão padrão.<input/>
lá em cima?Eu acho que este post ajudaria se alguém quiser fazer isso com o jQuery:
http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery/
A solução básica é:
e outro que eu gostei foi:
fonte
.wich
atributo. Também não há necessidade de voltar ao DOM.keyCode
(ou.charCode
para esse assunto).e.preventDefault();
o início desta função para evitar a execução do botão padrão "real". Funciona muito bem.Eu tinha um formulário com 11 botões de envio e ele sempre usava o primeiro botão de envio quando o usuário pressionava enter. Li em outro lugar que não é uma boa ideia (prática recomendada) ter mais de um botão de envio em um formulário, e a melhor maneira de fazer isso é ter o botão que você deseja como padrão, como o único botão de envio no formulário. Os outros botões devem ser transformados em "TYPE = BUTTON" e um evento onClick adicionado que chama sua própria rotina de envio em Javascript. Algo assim :-
Aqui, button3 é o padrão e, embora você esteja enviando programaticamente o formulário com os outros botões, a rotina mjsubmit os valida. HTH.
fonte
Agora isso pode ser resolvido usando
flexbox
:HTML
CSS
Explaination
Usando a caixa de flex, podemos inverter a ordem dos elementos em um recipiente que usos
display: flex
utilizando também a regra CSS:flex-direction: row-reverse
. Isso não requer CSS ou elementos ocultos. Para navegadores mais antigos que não oferecem suporte ao flexbox, eles ainda recebem uma solução viável, mas os elementos não serão revertidos.Demo
http://codepen.io/Godwin/pen/rLVKjm
fonte
Eu lutei com a mesma pergunta, já que eu tinha o botão enviar no meio do qual o redirecionado enviava para outra página, da seguinte forma:
Quando o usuário pressionou a tecla Enter, esse botão foi clicado em vez de outro botão de envio.
Então, eu fiz alguns testes primitivos criando um from com vários botões de envio e diferentes opções de visibilidade e um evento onclick alertando qual botão foi clicado: https://jsfiddle.net/aqfy51om/1/
Navegadores e sistemas operacionais que usei para testar:
JANELAS
OSX
A maioria desses navegadores clicou no primeiro botão, apesar das opções de visibilidade aplicadas, exceto o IE e o Safari, que clicaram no terceiro botão, que é "visível" dentro do contêiner "oculto":
Então, minha sugestão, que eu vou usar, é:
Se você formar vários botões de envio com significado diferente, inclua o botão de envio com a ação padrão no início do formulário, que é:
style="width: 0; height: 0; overflow: hidden;"
EDIT Outra opção pode ser o deslocamento do botão (ainda no começo do)
style="position: absolute; left: -9999px; top: -9999px;"
, tentei no IE - funcionou, mas não tenho idéia do que mais ele pode estragar, por exemplo, impressão ..fonte
Dos seus comentários:
Eu largo um
<input type="hidden" value="form_name" />
em cada formulário.Se estiver enviando com javascript: adicione eventos de envio aos formulários, não clique nos eventos nos respectivos botões. Usuários saavy não tocam o mouse com muita frequência.
fonte
Quando você tem vários botões de envio em um único formulário e um usuário pressiona a tecla ENTER para enviar o formulário a partir de um campo de texto, esse código substitui a funcionalidade padrão, chamando o evento de envio no formulário a partir do evento de pressionamento de tecla. Aqui está esse código:
fonte
Estranho que o primeiro botão Enter vá sempre para o primeiro botão, independentemente de estar visível ou não, por exemplo, usando jquery
show/hide()
. A adição de atributo.attr('disabled', 'disabled')
impede o recebimento completo do botão Enter submit. É um problema, por exemplo, ao ajustar a visibilidade do botão Inserir / Editar + Excluir nas caixas de diálogo de registro. Achei menos simples e simples colocar o Edit na frente de Inserte use o código javascript:
fonte
minha receita:
Ele enviará o campo oculto padrão se nenhum dos botões for 'clicado'.
se clicam, têm preferência e seu valor é passado.
fonte
Outra solução que usei é ter apenas um botão no formulário e falsificar os outros botões.
Aqui está um exemplo:
Eu, então, denomino os elementos de amplitude para parecerem um botão. Um ouvinte JS observa a extensão e executa a operação desejada uma vez clicada.
Não necessariamente adequado para todas as situações, mas pelo menos é bem fácil de fazer.
fonte
A partir da especificação do HTML 4 :
Isso significa que, dado mais de um botão de envio e nenhum ativado (clicado), nenhum deve ser bem-sucedido.
E eu argumentaria que isso faz sentido: imagine um formulário enorme com vários botões de envio. Na parte superior, há um botão "excluir este registro", depois várias entradas e, na parte inferior, um botão "atualizar este registro". Um usuário pressionando enter enquanto estiver em um campo na parte inferior do formulário nunca suspeitaria que ele implicitamente clicou no botão "excluir este registro" da parte superior.
Portanto, acho que não é uma boa ideia usar o primeiro ou qualquer outro botão que o usuário não defina (clique). No entanto, os navegadores estão fazendo isso, é claro.
fonte
EDIT: Desculpe, ao escrever esta resposta, eu estava pensando em enviar botões no sentido geral. A resposta abaixo não é sobre vários
type="submit"
botões, pois deixa apenas umtype="submit"
e altera o outro paratype="button"
. Deixo a resposta aqui como referência, caso ajude alguém que possa alterar atype
forma:Para determinar qual botão é pressionado ao pressionar Enter, você pode marcá-lo
type="submit"
e os outros botões os marcamtype="button"
. Por exemplo:fonte