Eu tenho um formulário que demora um pouco para o servidor processar. Preciso garantir que o usuário aguarde e não tente reenviar o formulário clicando no botão novamente. Tentei usar o seguinte código jQuery:
<script type="text/javascript">
$(document).ready(function() {
$("form#my_form").submit(function() {
$('input').attr('disabled', 'disabled');
$('a').attr('disabled', 'disabled');
return true;
});
});
</script>
Quando tento isso no Firefox, tudo fica desativado, mas o formulário não é enviado com nenhum dado do POST que ele deve incluir. Não posso usar o jQuery para enviar o formulário, pois preciso que o botão seja enviado com o formulário, pois existem vários botões de envio e determino qual foi usado pelo qual o valor de alguém está incluído no POST. Preciso que o formulário seja enviado como normalmente é e preciso desativar tudo logo após isso acontecer.
Obrigado!
Respostas:
Atualização em 2018 : recebi alguns pontos para esta resposta antiga e só queria acrescentar que a melhor solução seria tornar a operação idempotente para que envios duplicados sejam inofensivos.
Por exemplo, se o formulário criar um pedido, coloque um ID exclusivo no formulário. A primeira vez que o servidor vê uma solicitação de criação de pedido com esse ID, deve criá-la e responder "sucesso". Os envios subsequentes também devem responder "com êxito" (caso o cliente não tenha recebido a primeira resposta), mas não devem mudar nada.
As duplicatas devem ser detectadas por meio de uma verificação de exclusividade no banco de dados para evitar condições de corrida.
Eu acho que seu problema é esta linha:
Você está desativando TODAS as entradas, incluindo, eu acho, aquelas cujos dados o formulário deve enviar.
Para desativar apenas os botões de envio, você pode fazer o seguinte:
No entanto, acho que o IE não enviará o formulário se esses botões estiverem desativados. Eu sugeriria uma abordagem diferente.
Um plugin jQuery para resolvê-lo
Acabamos de resolver esse problema com o seguinte código. O truque aqui é usar o jQuery
data()
para marcar o formulário como já enviado ou não. Dessa forma, não precisamos mexer nos botões de envio, o que assusta o IE.Use-o assim:
Se houver formulários AJAX que devam ser autorizados a enviar várias vezes por carregamento de página, você poderá atribuir a eles uma classe indicando isso e excluí-los do seletor da seguinte maneira:
fonte
$(this)
para avar that = $(this)
?$form
embora - 'form' porque é mais descritivo, e o principal$
porque pela minha convenção, isso significa que é um objeto jQuery.A abordagem de tempo está incorreta - como você sabe quanto tempo a ação levará no navegador do cliente?
Como fazer isso
Quando o formulário é enviado, todos os botões de envio são desativados.
Lembre-se, no Firefox, quando você desabilita um botão, esse estado será lembrado quando você voltar ao histórico. Para impedir que você precise ativar os botões no carregamento da página, por exemplo.
fonte
Acho que a resposta de Nathan Long é o caminho a percorrer. Para mim, estou usando a validação do lado do cliente, então acabei de adicionar uma condição para que o formulário seja válido.
EDIT : Se isso não for adicionado, o usuário nunca poderá enviar o formulário se a validação do lado do cliente encontrar um erro.
fonte
event.timeStamp
não funciona no Firefox. Retornar false não é padrão, você deve ligarevent.preventDefault()
. E enquanto estamos nisso, sempre use chaves com uma construção de controle .Para resumir todas as respostas anteriores, aqui está um plugin que faz o trabalho e funciona em vários navegadores.
Para abordar o Kern3l, o método de temporização funciona para mim simplesmente porque estamos tentando parar um clique duplo no botão enviar. Se você tiver um tempo de resposta muito longo para um envio, recomendo substituir o botão ou o formulário de envio por um botão giratório.
O bloqueio completo dos envios subsequentes do formulário, como a maioria dos exemplos acima, tem um efeito colateral ruim: se houver uma falha na rede e eles quiserem tentar reenviá-los, eles não conseguirão fazê-lo e perderão as alterações que fez. Isso definitivamente deixaria um usuário irritado.
fonte
Por favor, confira o plugin jquery-safeform .
Exemplo de uso:
fonte
Corrigir. Os nomes / valores dos elementos do formulário desativados não serão enviados ao servidor. Você deve defini-los como elementos somente leitura .
Além disso, as âncoras não podem ser desativadas dessa maneira. Você precisará remover os HREFs (não recomendado) ou impedir o comportamento padrão (melhor maneira), por exemplo:
fonte
$('input[type=submit]').attr("disabled", "disabled");
mas minha maneira favorita é colocaronclick="this.disabled = 'disabled'"
o onclick do envio.Existe a possibilidade de melhorar a abordagem de Nathan Long . Você pode substituir a lógica para detecção do formulário já enviado por este:
fonte
Código de Nathan, mas para jQuery Validar plugin
Se você usa o plug-in jQuery Validate, eles já têm o manipulador de envio implementado e, nesse caso, não há razão para implementar mais de um. O código:
Você pode expandi-lo facilmente dentro do
} else {
bloco para desativar as entradas e / ou o botão enviar.Felicidades
fonte
Acabei usando as idéias deste post para encontrar uma solução bastante semelhante à versão do AtZako.
Usando assim:
Descobri que as soluções que não incluíam algum tempo limite, mas apenas desabilitaram o envio ou desabilitaram os elementos do formulário, causaram problemas porque, uma vez acionado o bloqueio, você não pode enviar novamente até atualizar a página. Isso causa alguns problemas para mim ao fazer coisas com ajax.
Provavelmente isso pode ser um pouco complicado, pois não é tão chique.
fonte
Se você estiver usando o AJAX para postar um formulário, o conjunto
async: false
deverá impedir envios adicionais antes que o formulário seja limpo:fonte
Modificou a solução de Nathan um pouco para o Bootstrap 3. Isso definirá um texto de carregamento para o botão enviar. Além disso, o tempo limite será excedido após 30 segundos e permitirá que o formulário seja reenviado.
fonte
Use dois botões de envio.
E jQuery:
fonte
Use um contador simples ao enviar.
E chamar a
monitor()
função em enviar o formulário.fonte
Estou tendo problemas semelhantes e minhas soluções são as seguintes.
Se você não possui nenhuma validação do lado do cliente, pode simplesmente usar o método jquery one () conforme documentado aqui.
http://api.jquery.com/one/
Isso desativa o manipulador depois que ele é invocado.
Se você estiver fazendo a validação do lado do cliente como eu, então é um pouco mais complicado. O exemplo acima não permitiria o envio novamente após falha na validação. Tente esta abordagem
fonte
Você pode parar o segundo envio por este
fonte
Minha solução:
fonte
No meu caso, a submissão do formulário tinha algum código de validação, então eu incremento a resposta de Nathan Long, incluindo um ponto de verificação de submissão
fonte
Alterar botão de envio:
Com botão normal:
Então use a função click:
E lembre-se de reativar o botão quando for necessário:
fonte
Não posso acreditar no bom e velho truque css dos eventos-ponteiro: nenhum ainda não foi mencionado. Eu tive o mesmo problema adicionando um atributo desativado, mas isso não é postado de volta. Experimente o abaixo e substitua #SubmitButton pelo ID do seu botão Enviar.
fonte
Enter
tecla.Por que não apenas isso? Isso enviará o formulário, mas também desativará o botão de envio,
Além disso, se você estiver usando o jQuery Validate, poderá colocar essas duas linhas em baixo
if ($('#myForm').valid())
.fonte
esse código exibirá o carregamento no rótulo do botão e defina o botão para
desabilite o estado e, após o processamento, reative e retorne o texto original do botão **
fonte
Resolvi um problema muito semelhante usando:
fonte