Control BotonEnviar para evitar doble clic en ASP .NET

Utilizamos el control personalizado Button de ASP .NET y JavaScript

Fecha: 18/Nov/2004 (12/11/2004)
Autor: Diego Rodero diego@rodero.info

 


 

Introducción: El Problema

¿Cuantas veces hemos desarrollado una aplicación Web con ASP .NET con nuestros botoncitos y todos nuestros controles bien diseñados, y nos falla porque el usuario hace clic dos veces en el botón y nos duplica las filas o nos da un error de Primary Key o cosas similares?.

En este artículo veremos como construir un control de tipo Button que tiene la funcionalidad de que cuando lo pulsamos se desabilita y modifica su texto por un texto que le indica al usuario que se está enviando el formulario. De esta manera evitaremos el posible "doble clic" del usuario:

La Solución

Vamos a crear un control web personalizado. Si teneis alguna librería de ellos, lo podeis añadir, si ya teneis experiencia. Si no teneis ninguna librería, abrimos el Visual Studio, Archivo -> Nuevo -> Proyecto -> Proyectos de Visual C# -> Biblioteca de Controles Web.

Ponemos el nombre que queramos a nuestra librería, en mi caso la he llamado RoderoLib, y le damos a Aceptar. Ahora cambiamos el nombre del fichero WebCustomControl1.cs por el nombre que le queramos dar a nuestro control, en mi caso la he llamado BotonEnviar.cs. Ahora abrimos este fichero y nos ponemos a desarrollar nuestro control.


using System;
using System.Web.UI;
using System.ComponentModel;

namespace RoderoLib
{
	/// 
	/// Control "Button" o Botón con la funcionalidad de poder hacer un solo clic
	/// 
	[ToolboxData("<{0}:BotonEnviar runat=server></{0}:BotonEnviar>")]
	public class BotonEnviar : System.Web.UI.WebControls.Button	
	{
		private string _TextoEnviando = "Enviando...";
	
		[Bindable(true), 
		Category("Appearance"), 
		DefaultValue("Enviando..."),
		Description("Texto a mostrar cuando se pulse el botón")]
		public string TextoEnviando
		{
			get
			{
				return _TextoEnviando;
			}

			set
			{
				_TextoEnviando = value;
			}
		}
Como vemos, hemos creado una propiedad TextoEnviando donde vamos a almacenar el texto que tendrá nuestro botón cuando lo pulsemos. También hemos creado un campo privado para almacenar este texto. Continuamos:
		public BotonEnviar()
		{
			base.Text = "Enviar";
			base.CausesValidation = false;
		}

Con esto, hemos creado el constructor de nuestro control, en el que modificamos el texto por defecto a Enviar y modificamos su comportamiento para que no cause validación. Nosotros nos encargaremos de comprobar que esta validación funciona correctamente. Seguimos:

		protected override void OnPreRender(EventArgs e)
		{
			//Registramos la función de envío del botón
			Page.RegisterClientScriptBlock("fEnviar_" + ID,FunciónEnviarBotón());
			base.OnPreRender(e);
		}

Reescribimos el método OnPreRender para registrar la función JavaScript que utilizaremos para nuestro botón. Ahora vemos el método Render donde escribimos nuestro control:

		protected override void Render(HtmlTextWriter output)
		{			
			//Creamos el panel donde va el botón principal
			output.Write("<div id='div1_" + ID + "' style='display: inline'>");			

			output.AddAttribute("onclick","Enviar_" + ID + "('" + ID +"');");
			base.Render(output);

			output.Write("</div>");
			
			//Creamos el panel y el botón secundario de envío
			output.Write("<div id='div2_" + ID + "' style='display: none'>");	
			output.Write("<input disabled type=submit value='" + TextoEnviando + "' />");	
			output.Write("</div>");			
			
		}

Lo que hacemos es crear dos Paneles, o elementos div, uno donde colocamos nuestro botón normal, y otro panel donde colocamos un botón sin funcionalidad, cuyo texto es el texto que le hemos indicado en la propiedad TextoEnviando. Este botón estará deshabilitado y el panel con la propiedad display a none. Ya solo nos queda escribir la función JavaScript que se llama cuando pulsamos nuestro botón:

		private string FunciónEnviarBotón()
		{
			string txt = "<script language='javascript'>";

			txt += @"function Enviar_" + ID + @ "(id) {
						if (typeof(Page_ClientValidate) == 'function') {
							if (Page_ClientValidate() == true ) { 
								document.getElementById('div1_' + id).style.display = 'none';
								document.getElementById('div2_' + id).style.display = 
							'inline';							return true;
							}
							else {
								return false;
							}
						}
						else {	
							document.getElementById('div1_' + id).style.display = 'none';
							document.getElementById('div2_' + id).style.display = 'inline';
							return true;
						}

					}</script>;"
			
			return txt;
		}

Con esta función JavaScript, lo que hacemos es que cuando pulsamos nuestro botón, ponemos la propiedad display de este panel a none y la propiedad display del panel secundario a inline. De esta manera parece que nuestro botón se ha desabilitado y cambiado de texto. No podemos poner directamente el botón a disabled porque entonces no se ejecutaría el código asociado a ese botón del lado del servidor. También vemos como el código comprueba que se hayan cumplido los validadores si la página los tiene.

Una vez que hemos llegado hasta aquí, compilamos nuestra solución. Ahora, para incluir el botón en nuestra aplicación, nos vamos a una página .aspx, hacemos clic en el Cuadro de Herramientas -> botón derecho -> Agregar o Quitar elementos -> Examinar -> Buscamos el directorio bin\debug de nuestra solución, y escogemos la dll. Aceptamos y ya tenemos nuestro botón con esta nueva funcionalidad en nuestra aplicación.

Conclusión

Como vemos, con muy poquito código podemos tener un botón que nos quitará muchos quebraderos de cabeza a la hora de desarrollar nuestras aplicaciones con ASP .NET.

Si te ha gustado, te ha dado alguna buena idea o te ha servido este artículo, puedes votarlo en la parte superior de la página. Por supuesto, si consideras que el artículo no merece la pena, también lo puedes puntuar como tal.


ir al índice

Fichero con la solución de ejemplo: DiegoRodero_ControlBotonEnviar.zip - 38.4 KB