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: