2010-05-21 10 views
8

Tengo una aplicación asp.net que quiero deshabilitar los botones tan pronto como se hacen clic para evitar múltiples envíos. Me gustaría usar jquery para esto, ya que el sitio ya lo usa liberalmente de todos modos.Desactivar botones en la publicación posterior usando jquery en la aplicación .net

Lo que he intentado es:

$(document).ready(function() { 
    $("#aspnetForm").submit(function() { 
     $('input[type=submit]', $(this)).attr("disabled", "disabled"); 
    }) 
}); 

Lo anterior se desactivará el botón, y la página sostiene, pero el botón de asp.net controlador de clic no se llama. Simplemente eliminar lo anterior y los botones funcionan normalmente.

¿Hay una manera mejor? O, mejor dicho, ¿qué estoy haciendo mal?

ACTUALIZACIÓN Bien, finalmente tuve un poco de tiempo para juntar una página muy simple.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SubTest.aspx.cs" Inherits="MyTesting.SubTest" %> 

<!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 src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
     $(function() { 
      $("#form1").submit(function() { 
       $('input[type=submit]', $(this)).attr("disabled", "disabled"); 
      }); 
     }); 
    </script> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" /> 
     <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button 2" /> 
    </div> 
    </form> 
</body> 
</html> 

El código se ve atrás como:

using System; 

namespace MyTesting { 
    public partial class SubTest : System.Web.UI.Page { 
    protected void Page_Load(object sender, EventArgs e) { 
     if (IsPostBack) { 
      // this will execute when any button is pressed 
      Response.Write("postback"); 
     } 
    } 
     protected void Button1_Click(object sender, EventArgs e) { 
     // never executes 
      System.Threading.Thread.Sleep(1000); 
      Response.Write("Button 1 clicked<br />"); 
     } // method::Button1_Click 

     protected void Button2_Click(object sender, EventArgs e) { 
     // never executes 
      System.Threading.Thread.Sleep(1000); 
      Response.Write("Button 2 clicked<br />"); 
     } // method::Button2_Click 
    } 
} 

Al hacer clic en un botón que, obviamente, desactiva los botones, pero ninguno de los clics de los botones se ejecutan.

HTML representado

<!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><title> 

</title> 
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
     $(function() { 
      $("#form1").submit(function() { 
       $('input[type=submit]', $(this)).attr("disabled", "disabled"); 
      }); 
     }); 
    </script> 
</head> 
<body> 
    <form name="form1" method="post" action="SubTest.aspx" id="form1"> 
<div> 
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTcxODU4OTc0MWRkParC5rVFUblFs8AkhNMEtFAWlU4=" /> 
</div> 

<div> 

    <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKB57WhCAKM54rGBgK7q7GGCC6LlWKFoij9FIBVuI0HOVju/fTy" /> 
</div> 
    <div> 
     <input type="submit" name="Button1" value="Button" id="Button1" /> 
     <input type="submit" name="Button2" value="Button 2" id="Button2" /> 
    </div> 
    </form> 
</body> 
</html> 
+0

muy interesante Gotchya –

+0

creo que sé exactamente lo que está pasando ahora. Debido a que el atributo de botón está desactivado, el motor de asp.net dice "¡oh, el botón está deshabilitado, no ejecute su código posterior de publicación!" Sin embargo, como se envió un envío, sigue adelante y realiza una publicación normal de nuevo ... grr – NotMe

Respuesta

1

Sólo quería t o agregue una resolución adicional. Decidimos eliminar por completo el botón una vez que se hizo clic y reemplazarlo con un poco de texto.

para hacer esto que hicimos:

$(function() { 
    $(".DisableButton").click(function() { 
     $(this).hide(); 
     $(this).after('<p>Please Wait. Retrieving information. This may take up to 60 seconds.</p>'); 

    }); 
}); 

Tenga en cuenta que esto oculta el botón y luego inyecta algo de HTML después de que el código de botones. Ocultarlo permite que .Net avance y ejecute el controlador onclick durante la publicación posterior mientras lo elimina como algo que se puede hacer clic en la pantalla.

+0

Gracias, esta fue la respuesta más simple que he visto hasta ahora. –

7

usted puede hacerlo de una manera ligeramente diferente, como esto:

$(function() { 
    $("#aspnetForm").submit(function() { 
    $('input[type=submit]').click(function() { return false; }); 
    }); 
}); 

Lo que esto hace es que hace que los futuros clics ineficaces, por lo que básicamente no hacen nada. Cuando deshabilita una entrada, también elimina que el par clave/valor se envíe con el <form>, por lo que la acción del lado del servidor que se desencadena no funciona.

Vale la pena señalar, en jQuery 1.4.3 podrás acortar esto a:

$(function() { 
    $("#aspnetForm").submit(function() { 
    $('input[type=submit]').click(false); 
    }); 
}); 
+0

Ahora estoy ejecutando 1.4.2. el primero no parece detener la pulsación de múltiples botones; – NotMe

+0

@Chris - ¿Puedes publicar tu marcado? ¿Está utilizando botones de envío o posiblemente enlaces también? –

+0

@Nick Craver: Finalmente tuve la oportunidad de publicar un marcado – NotMe

0

Si tiene controles de validación ASP.NET en la página de su se complica. Pero esto ha sido respondida antes: Disable button on form submission

+0

Lo intenté. Aparece un error de compilación: el nombre 'ClientScript' no existe en el contexto actual. Si saco la línea que hace referencia a 'ClientScript', el botón está deshabilitado, pero nunca envía – NotMe

+0

¿Está intentando esto en un control en lugar de en la página? De ser así, deberá hacer referencia a la propiedad de ClientScript en la página, p. 'Page.ClientScript.GetPostBackEventReference (btnSubmit, string.Empty)'. – jrummell

+0

Está en una página y no hay validación. Acabo de actualizar mi respuesta con el marcado. – NotMe

2

El enfoque de deshabilitar el botón antes de que presenten tiene dos efectos: -

a) El botón toma la apariencia discapacitados.

b) El valor del botón no se publica en los parámetros del formulario.

Si el valor del botón no se publica en el servidor, ASP.Net no sabe qué botón se ha pulsado y, por lo tanto, no ejecuta el controlador OnClick correspondiente.

Para verificar añadir lo siguiente a su código detrás

protected void Page_Load(object sender, EventArgs e) 
{ 
    Response.Write("Load " + IsPostBack + "<br />"); 
    foreach (string s in Request.Form.AllKeys) 
    { 
     Response.Write(string.Format("s:'{0}' = {1}<br />", s, Request.Form[s])); 
    } 
} 

Y a continuación, ejecutar la página (ambos con J. S. desactivar los botones y sin). Si el valor del botón no se publica en el servidor, ASP.Net no sabe qué botón se presionó y, por lo tanto, no ejecuta el controlador OnClick correspondiente.

+0

+1 Este fue mi hallazgo exactamente. Como dijiste, es una gotchya interesante. – NotMe

2

Solo otra observación. Alternativamente, puede bloquear la IU con un bonito mensaje ocupado de superposición.

La parte de Mark-up:

$(function() { // when document has loaded 

    ($.unblockUI); //unlock UI 

    //Show busy message on click event and disable UI 
    $('#btnHelloWorld').click(function() { 
    $.blockUI({ message: '<h4><img src="busy.gif" />Please wait...</h4>' }); 

    }); 

}); 

<asp:Button ID="btnHelloWorld" runat="server" Text="Hello World" /><br/> 

el código detrás:

Protected Sub btnHelloWorld_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnHelloWorld.Click 
     Label1.Text = "Hello World" 
     Threading.Thread.Sleep(5000) 
    End Sub 

Salida jQuery BlockUI Plugin

+0

Enfoque interesante. Tendré que probar esto. – NotMe

0

Añadir este atributo a su botón:

usesubmitbehavior="False" 

Esto insertará algo así como lo siguiente en onclick:

javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$Main$Tabs$SaveTab$Cancel", "", true, "", "", false, false)) 

Este código hará que un post posterior, incluso si el botón está desactivado. Mostrando un diálogo de confirmación y permitiendo el segundo palo que ser cancelado se vuelve un poco más interesante:

var click = $("[id$='_Cancel']")[0].onclick; 
    $("[id$='_Cancel']")[0].onclick = null; 
    $("[id$='_Cancel']").bind('click', function (event) { addFeeSchedule.onCancelClick(event) }); 
    $("[id$='_Cancel']").bind('click', click); 

Con el fin de evitar que el segundo palo que se produzcan inmediatamente, eliminar el código insertado por onclick .net y enlazarlo después de su propia funciona usando jQuery. Utilice event.stopImmediatePropagation(), para evitar el segundo palo:

onCancelClick: function (event) { 

    var confirmResponse; 

    confirmResponse = confirm('No fee schedule will be created.\n\nAre you sure you want to cancel?'); 

    if (confirmResponse == true) { 

     showWait(); 
     event.target.disabled = 'true'; 

    } else { 

     event.stopImmediatePropagation(); 

    } 

}, 
-3

Para ello se tiene que utilizar el botón de entrada de atributos desactivar todos los controles

<script language="javascript" type="text/javascript"> 
    function MyDisableFunction() { 
     alert(`Now You Postback Start`); 
     $(":input").attr("disabled", true); 
     return true; 
    } 

</script> 

Para mayor detalle cheque this link

+1

promoción de blog personal no se acepta aquí .. – rahularyansharma

0

la respuesta dada por Nick Craver es, de lejos, la mejor solución que he encontrado en cualquier lugar de la red. Sin embargo, hay una situación en la que la solución no funciona bien: cuando el formulario contiene botones de envío dentro de un UpdatePanel con su propiedad UpdateMode configurada en "Conditional" y/o la propiedad ChildrenAsTriggers establecida en false.

En estas situaciones, los contenidos de los paneles de actualización no se actualizan automáticamente cuando se completa la devolución de datos asincrónica. Entonces, si estos paneles de actualización contienen algún botón de envío, la solución dada dejaría estos botones permanentemente desactivados.

La siguiente mejora a la solución maneja este problema volviendo a habilitar los botones después de una asíncrona, o 'parcial', la devolución de datos:

var canProcessClicks = true; 

if (typeof (Sys) != 'undefined') { 
    // handle partial-postback 
    var requestManager = Sys.WebForms.PageRequestManager.getInstance(); 
    requestManager .add_initializeRequest(function() { 
     // postback started 
     canProcessClicks = false; 
    }); 
    requestManager .add_endRequest(function() { 
     // postback completed 
     canProcessClicks = true; 
    }); 
} 

$(function() { 
    $('input[type=submit]').on("click", function() { 
     return canProcessClicks ; 
    }); 
    $("#aspnetForm").submit(function() { 
     if (typeof (Sys) != 'undefined' && Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) { 
      // this is an async postback so ignore because this is already handled 
     } else { 
      // full postback started 
      canProcessClicks = false; 
     } 
    }); 
}); 
Cuestiones relacionadas