ASP
.NET - Desabilitando o botão de comando após o primeiro click
do usuário
Pode parecer sem importância mas a possibilidade do usuário clicar mais de uma vez em um botão de comando e assim disparar a execução de um novo processo/evento pode trazer muitas dores de cabeça.
Eu mesmo enfrentei esse problema em uma aplicação web onde o cliente confirmava uma transação financeira clicando em um botão de comando que disparava a execução da transação.
Se o cliente clicasse rapidamente duas vezes no botão eram iniciados duas transações levando a uma duplicidade na execução da transação o que naturalmente gerava uma anotação de débito em duplicidade na conta do cliente que não ficava muito feliz com isso.
Neste artigo eu vou mostrar uma das possibilidades de contornar o problema em uma aplicação ASP .NET.
Mas como você resolveria esta situação ?
Desativar um botão para evitar que ele seja clicado mais de uma vez pode parecer fácil a primeira vista.
Talvez a primeira coisa que lhe venha à mente para desabilitar o botão de comando é adicionar o seguinte código no lado do servidor: button.Enabled = false
E porque não ?
Afinal o código desabilita o botão atribuindo o valor à sua propriedade Enabled. Certo ??
Errado !!!
Infelizmente isso não vai desativar o botão uma vez que o botão tem que dar um post back para o servidor para executar a instrução.
Portanto você não pode usar o código do lado do servidor.
E então como resolvemos isso ?
A solução (uma das possíveis) é simples, e eu vou mostrar 3 variações da mesma solução que usa o evento OnClientClick do lado do cliente.
Resolvendo o problema
Como exemplo vou criar um projeto usando o Visual Web Developer 2010 Express Edition selecionando o menu New Project e escolhendo o template ASP .NET Empty Web Application com o nome: DesabilitarBotao
![]() |
Agora vamos incluir 3 formulários web no projeto para apresentar as nossas soluções.
No menu Project clique em Add New Item, selecione o template Web Form e aceite o nome padrão WebForm1.aspx;
![]() |
Repita o procedimento acima e inclua mais dois formulários web : WebForm2.aspx e WebForm3.aspx.
1 - No formulário WebForm1.aspx inclua um controle Button (Button1) conforme mostra o código e leiaute a seguir:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="DesabilitarBotao.WebForm1" %> <!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"> <head runat="server"> <title></title> <style type="text/css"> .style1 { color: #0033CC; } </style> </head> <body> <form id="form1" runat="server"> <h1 class="style1">Macoratti .net </h1> <hr /> <div> <asp:Button ID="Button1" runat="server" Text="Confirmar Pedido" onclick="Button1_Click" Width="234px" Height="26px" /> </div> </form> </body> </html> |
![]() |
No code-behind inclua no arquivo WebForm1.aspx.cs o seguinte código:
using System; namespace DesabilitarBotao { public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Button1.Attributes.Add("onclick", "document.body.style.cursor = 'wait'; this.value='Aguarde, Enviando...'; this.disabled = true; " + this.GetPostBackEventReference(Button1, string.Empty) + ";"); } protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(5000); } } } |
Neste código estamos adicionando o código JavaScript para desabilitar o botão ao evento onclick anexando-o à coleção Attributes do controle Button e então chamando a referencia ao evento Post Back para o botão após desabilitá-lo.
A propriedade Attributes permite adicionar HTML aos elementos de uma página :
Button1.Attributes.Add("onclick", "alert('Macoratti')"); Button1.Style.Add("background-color", "red"); body.Attributes["bgcolor"] = "lightblue"; |
Executando o projeto iremos obter:
![]() |
![]() |
2 - No formulário WebForm2.aspx inclua um controle Button (Button1) e uma caixa de texto(txtDataSubmit) conforme mostra o código e leiaute a seguir:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="DesabilitarBotao.WebForm2" %> <!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"> <head runat="server"> <title></title> <script language="javascript" type="text/javascript"> // desabilita o botao function disableButtonOnClick(oButton, sButtonText) { oButton.disabled = true; // altera o texto do botão oButton.value = sButtonText; } </script> <style type="text/css"> .style1 { color: #0033CC; } </style> </head> <body> <form id="form1" runat="server"> <h1 class="style1">Macoratti .net </h1> <hr /> <div> Data de envio : <asp:TextBox ID="txtDataSubmit" runat="server"></asp:TextBox> <asp:Button ID="btnSubmit" runat="server" Text="Enviar Dados" onclick="btnSubmit_Click" /> <br /> </div> </form> </body> </htm> |
|
![]() |
Neste código definimos uma função JavaScript chamada disableButtonOnclick para desabilitar o botão.
No code-behind inclua no arquivo WebForm2.aspx.cs o seguinte código:
using System; using System.Web.UI; namespace DesabilitarBotao { public partial class WebForm2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { PostBackOptions optionsSubmit = new PostBackOptions(btnSubmit); btnSubmit.OnClientClick = "disableButtonOnClick(this, 'Aguarde...'); "; btnSubmit.OnClientClick += ClientScript.GetPostBackEventReference(optionsSubmit); } protected void btnSubmit_Click(object sender, EventArgs e) { // simula a carga no servidor por 2 segundos System.Threading.Thread.Sleep(2000); // define a data no textbox txtDateSubmit.Text = DateTime.Now.ToString(); } } } |
A ASP.NET apresenta a classe ClientScriptManager que contém métodos que podem ser usados para incluir código JavaScript no cliente. Os métodos da classe Page são também disponibilizados por esta nova classe e apresenta uma nova propriedade ClientScript que permite usar a nova classe, ou seja , podemos acessar a classe ClientScriptManager através de Page.ClientScript.
O método ClientScript.GetPostBackEventReference devolve uma cadeia que pode ser usada em um evento do cliente para causar um postback para o servidor. A seqüência de referência é definido pelo controle especificado que manipula o postback e um argumento de seqüência de informações de eventos adicionais.
Executando o projeto iremos obter:
![]() |
![]() |
|
![]() |
3 - No formulário WebForm3.aspx inclua um controle Button (Button1) conforme mostra o código e leiaute a seguir:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="DesabilitarBotao.WebForm3" %> <!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"> <head runat="server"> <title></title> <style type="text/css"> .style1 { color: #0033CC; } </style> </head> <body> <form id="form1" runat="server"> <h1 class="style1">Macoratti .net </h1> <hr /> <div> <asp:Button runat="server" ID="BtnSubmit" OnClientClick="this.disabled = true; this.value = 'Enviando...';" UseSubmitBehavior="false" OnClick="BtnSubmit_Click" Text="Clique aqui para enviar!" /> </div> </form> </body> </html> |
|
![]() |
Neste código definimos o código JavaScript no evento OnClientClick e definimos a propriedade Button.UseSubmitBehavior como false.
a propriedade Button.UseSubmitBehavior obtém ou define um valor indicando se o controle Button usa o mecanismo de envio do navegador do cliente(true) ou o mecanismo postback da ASP.NET (false). O valor padrão é true.
No code-behind inclua no arquivo WebForm3.aspx.cs o seguinte código:
using System; namespace DesabilitarBotao { public partial class WebForm3 : System.Web.UI.Page { protected void BtnSubmit_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(4000); } } } |
Executando o projeto teremos o seguinte resultado:
![]() |
![]() |
As 3 soluções apresentam o mesmo resultado. Escolha a mais adequada ou defina uma solução melhor.
Pegue o projeto completo
aqui:
DesabilitarBotao.zip
1Ts 5:4
Mas vós, irmãos, não estais em trevas, para que aquele dia, como ladrão, vos surpreenda;1Ts 5:5
porque todos vós sois filhos da luz e filhos do dia; nós não somos da noite nem das trevas;1Ts 5:6
não durmamos, pois, como os demais, antes vigiemos e sejamos sóbrios.Referências: