Porque é que o formulário de postagem quando eu desativar o botão enviar para evitar um duplo clique?
-
03-07-2019 - |
Pergunta
Como qualquer outro desenvolvedor web no planeta, eu tenho um problema com usuários um duplo clique no botão enviar em meus formulários. Meu entendimento é que a maneira convencional para lidar com este problema, é desativar o botão imediatamente após o primeiro clique, no entanto, quando eu fizer isso, não publicar .
Eu fiz alguma pesquisa sobre isso, Deus sabe há informação suficiente, mas outras questões como Disable botão no formulário de submissão , desativando o botão aparece ao trabalho. O cartaz original de após submeter parece ter tido o mesmo problema que eu, mas há há menção sobre como / se ele resolveu-lo.
Aqui está um código de como a repeti-lo (testado no IE8 Beta2, mas tinha mesmo problema no IE7)
Meu código aspx
<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<script language="javascript" type="text/javascript">
function btn_onClick()
{
var chk = document.getElementById("chk");
if(chk.checked)
{
var btn = document.getElementById("btn");
btn.disabled = true;
}
}
</script>
<body>
<form id="form1" runat="server">
<asp:Literal ID="lit" Text="--:--:--" runat="server" />
<br />
<asp:Button ID="btn" Text="Submit" runat="server" />
<br />
<input type="checkbox" id="chk" />Disable button on first click
</form>
</body>
</html>
código My cs
using System;
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
btn.Click += new EventHandler(btn_Click);
btn.OnClientClick = "btn_onClick();";
}
void btn_Click(object sender, EventArgs e)
{
lit.Text = DateTime.Now.ToString("HH:mm:ss");
}
}
Observe que quando você clica no botão, uma nova postagem ocorre, eo tempo é atualizado. Mas quando você marcar a caixa de seleção, a próxima vez que clicar no botão, o botão está desativado (como esperado), mas nunca faz a postagem.
O que diabos eu falto aqui ???
Agradecemos antecipadamente.
Solução
Eu acho que você está apenas perdendo esta tag:
UseSubmitBehavior="false"
Tente assim:
<asp:Button ID="btnUpdate" runat="server" UseSubmitBehavior="false" OnClientClick="if(Page_ClientValidate()) { this.disabled = true; } else {return false;}" Text = "Update" CssClass="button" OnClick="btnUpdate_Click" ValidationGroup="vgNew"/>
Outras dicas
fallen888 está certo, sua abordagem não funciona cross-browser. Eu uso este pequeno trecho para evitar dupla clique.
convertidos UseSubmitBehavior="false"
botão enviar para o botão normal (<input type="button">
). Se você não quer que isso aconteça, você pode ocultar botão enviar e imediatamente inserção botão desativado no seu lugar. Porque isso acontece tão rapidamente que vai olhar como botão de se tornarem deficientes para o usuário. Os detalhes estão no blog de Josh Stodola .
Exemplo de código (jQuery):
$("#<%= btnSubmit.ClientID %>").click(function()
{
$(this)
.hide()
.after('<input type="button" value="Please Wait..." disabled="disabled" />');
});
"Desativar" controles HTML nem sempre produz um comportamento consistente em todos os principais navegadores. Então, eu tento ficar longe de fazer isso no lado do cliente, porque (trabalhando com o modelo ASP.NET) que você precisa para manter o controle de estado do elemento no cliente e servidor nesse caso.
O que eu faria é botão mover para fora da parte visível da janela, alternando className do botão para uma classe CSS que contém o seguinte:
.hiddenButton
{
position: absolute;
top: -1000px;
left: -1000px;
}
Agora, o que colocar no lugar do botão?
- Ou uma imagem que parece um botão desativado
- Ou apenas texto simples que diz "Por favor, aguarde ..."
E isso pode ser feito da mesma maneira mas em sentido inverso. Comece com o elemento que está sendo escondido no carregamento da página e, em seguida, mudar para um className visível no formulário de envio.
Nós usamos o seguinte JQuery roteiro, para desativar todos os botões (input type = submeter e botão), quando o um botão é clicado.
Nós apenas incluiu o script em um arquivo JavaScript global, de modo que não temos de fazer lembrar de nada ao criar novos botões.
$(document).ready(function() {
$(":button,:submit").bind("click", function() {
setTimeout(function() {
$(":button,:submit").attr("disabled", "true");
}, 0);
});
});
Este script poderia facilmente ser estendido com um cheque de Page_ClientValidate ().
document.getElementById('form1').onsubmit = function() {
document.getElementById('btn').disabled = true;
};
Esta é a maneira correta e simples de fazer isso:
Ele funciona em todos os navegadores (ao contrário da solução aceita acima).
Criar um método auxiliar na aplicação (dizer em um Namespace Utlity):
Public Shared Sub PreventMultipleClicks(ByRef button As System.Web.UI.WebControls.Button, ByRef page As System.Web.UI.Page)
button.Attributes.Add("onclick", "this.disabled=true;" + page.ClientScript.GetPostBackEventReference(button, String.Empty).ToString)
End Sub
Agora, a partir do código por trás de cada uma das páginas da web que você pode simplesmente chamar:
Utility.PreventMultipleClicks(button1, page)
onde button1 é o botão que você quer evitar vários cliques.
O que isto faz é simplesmente define o manipulador de clique para: this.disabled = true
e, em seguida, anexa os botões próprio manipulador posto de volta, então temos:
onclick = "this.disabled = true"; __ doPostBack ( 'ID $ ID', ''); "
Esta não quebrar o comportamento padrão da página e funciona em todos os navegadores como o esperado.
Aproveite!
Para fins de depuração, o que acontece se você colocar uma cláusula else contra o if (chk.checked)?
Certifique-se de que seus função retorna javascript verdadeiros (ou um valor que iria avaliar a boolean true), caso contrário o formulário não vai ficar submetido.
function btn_click()
var chk = document.getElementById("chk");
if(chk.checked)
{
var btn = document.getElementById("btn");
btn.disabled = true;
return true; //this enables the controls action to propagate
}
else return false; //this prevents it from propagating
}
USUÁRIOS para jQuery
Você vai entrar em todos os tipos de problemas ao tentar adicionar o javascript diretamente para o evento onClick em ASP.NET botões quando usando jQuery ouvintes de eventos.
Eu encontrei a melhor maneira de desativar os botões e obter a postagem de trabalho foi fazer algo como isto:
$(buttonID).bind('click', function (e) {
if (ValidateForm(e)) {
//client side validation ok!
//disable the button:
$(buttonID).attr("disabled", true);
//force a postback:
try {
__doPostBack($(buttonID).attr("name"), "");
return true;
} catch (err) {
return true;
}
}
//client side validation failed!
return false;
});
Onde ValidateForm é a sua função de validação personalizada que retorna verdadeiro ou falso se o formulário valida lado do cliente.
e buttonID é o ID do seu botão como '# button1'