2008-09-20 73 views
15

Tengo un botón que me gustaría desactivar cuando se envía el formulario para evitar que el usuario lo envíe varias veces.Botón Deshabilitar en el envío del formulario

He intentado desactivar ingenuamente el botón con javascript onclick pero luego si una validación del lado del cliente que falla el botón permanece desactivada.

¿Cómo desactivo el botón cuando el formulario envía correctamente no solo cuando el usuario hace clic?

Este es un formulario de ASP.NET así que me gustaría conectarme muy bien con el ciclo de vida de la página asp.net ajax si es posible.

Respuesta

14

dar a esto un torbellino:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Threading; 

public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

     // Identify button as a "disabled-when-clicked" button... 
     WebHelpers.DisableButtonOnClick(buttonTest, "showPleaseWait"); 
    } 

    protected void buttonTest_Click(object sender, EventArgs e) 
    { 
     // Emulate a server-side process to demo the disabled button during 
     // postback. 
     Thread.Sleep(5000); 
    } 
} 



using System; 
using System.Web; 
using System.Web.UI.WebControls; 
using System.Text; 

public class WebHelpers 
{ 
    // 
    // Disable button with no secondary JavaScript function call. 
    // 
    public static void DisableButtonOnClick(Button ButtonControl) 
    { 
     DisableButtonOnClick(ButtonControl, string.Empty);  
    } 

    // 
    // Disable button with a JavaScript function call. 
    // 
    public static void DisableButtonOnClick(Button ButtonControl, string ClientFunction) 
    { 
     StringBuilder sb = new StringBuilder(128); 

     // If the page has ASP.NET validators on it, this code ensures the 
     // page validates before continuing. 
     sb.Append("if (typeof(Page_ClientValidate) == 'function') { "); 
     sb.Append("if (! Page_ClientValidate()) { return false; } } "); 

     // Disable this button. 
     sb.Append("this.disabled = true;"); 

     // If a secondary JavaScript function has been provided, and if it can be found, 
     // call it. Note the name of the JavaScript function to call should be passed without 
     // parens. 
     if (! String.IsNullOrEmpty(ClientFunction)) 
     { 
      sb.AppendFormat("if (typeof({0}) == 'function') {{ {0}() }};", ClientFunction); 
     } 

     // GetPostBackEventReference() obtains a reference to a client-side script function 
     // that causes the server to post back to the page (ie this causes the server-side part 
     // of the "click" to be performed). 
     sb.Append(ButtonControl.Page.ClientScript.GetPostBackEventReference(ButtonControl) + ";"); 

     // Add the JavaScript created a code to be executed when the button is clicked. 
     ButtonControl.Attributes.Add("onclick", sb.ToString()); 
    } 
} 
+0

gracias rp. esto se ve increíble – Brownie

+1

¡Guau! ¡Pareces ser un codificador de nivel empresarial! :) –

+0

rp. un pequeño cambio que tuve que hacer fue pasar mi nombre de grupo de validación al método Page_ClientValidate(). Gracias por el código! – Brownie

2

Desactive el botón al final de su controlador de envío. Si la validación falla, debe devolver falso antes de eso.

Sin embargo, el enfoque de JavaScript no es algo en lo que se pueda confiar, por lo que también debe tener algo para detectar duplicados en el servidor.

5

La siguiente función es útil sin la necesidad de la parte de desactivación que tiende a ser poco confiable. Simplemente use "return check_submit();" como parte del controlador onclick de los botones de envío.

También debe haber un campo oculto para mantener el valor inicial de form_submitted de 0;

<input type="hidden" name="form_submitted" value="0"> 

function check_submit(){ 
      if (document.Form1.form_submitted.value == 1){ 
       alert("Don't submit twice. Please wait."); 
       return false; 
      } 
      else{ 
       document.Form1.form_submitted.value = 1; 
       return true; 
      } 
      return false; 
    } 
+0

Una gran cantidad de grandes respuestas aquí, pero esto uno es hermoso – Sean

0

Una solución será la creación de un campo oculto cuando se hace clic en el botón, con el número 1.

En el clic de botón manejador Lo primero es comprobar que el número si es algo distinto de 1 solo regresa de la función.

0

También puede aprovechar el evento javascript onsubmit() que está disponible en los formularios. Este evento se activa cuando el formulario se envía y no debe atraparse hasta que se complete la validación.

2

si la validación es exitosa, entonces desactivar el botón. si no es así, entonces no.

function validate(form) { 
    // perform validation here 
    if (isValid) { 
    form.mySubmitButton.disabled = true; 
    return true; 
    } else { 
    return false; 
    } 
} 

<form onsubmit="return validate(this);">...</form> 
0

Este es un método más fácil, pero similar a lo que rp ha sugerido:

function submit(button) { 
     Page_ClientValidate(); 
     if(Page_IsValid) 
     { 
      button.disabled = true; 
     } 
} 

<asp:Button runat="server" ID="btnSubmit" OnClick="btnSubmit_OnClick" OnClientClick="submit(this)" Text="Submit Me" /> 
1

establecer la visibilidad en el botón 'none';


btnSubmit.Attributes("onClick") = document.getElementById('btnName').style.display = 'none';

No sólo impide a la doble presentación, pero es un claro indicador de que el usuario no desea que el botón presionado más de una vez.

+0

esta es una buena idea. – MGOwen

+0

... aunque prefiero utilizar el atributo OnClientClick, no el código subyacente. – MGOwen

+0

... ¿y no lo necesitará para que no desaparezca si falla la validación del lado del cliente? – MGOwen

17

No soy un gran fan de escribir todo ese javascript en el código subyacente. Así es como se ve mi solución final.

Botón:

<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" OnClientClick="doSubmit(this)" /> 

Javascript:

<script type="text/javascript"><!-- 
function doSubmit(btnSubmit) { 
    if (typeof(Page_ClientValidate) == 'function' && Page_ClientValidate() == false) { 
     return false; 
    }  
    btnSubmit.disabled = 'disabled'; 
    btnSubmit.value = 'Processing. This may take several minutes...'; 
    <%= ClientScript.GetPostBackEventReference(btnSubmit, string.Empty) %>;  
} 
//--> 
</script> 
+0

+1. Buen toque con el 'Processing ...' msg –

+0

excelente código! – drogon

0

acabamos de escuchar acerca de la propiedad "DisableOnSubmit" de un asp <: Botón >, así:

<asp:Button ID="submit" runat="server" Text="Save" 
    OnClick="yourClickEvent" DisableOnSubmit="true" /> 

Cuando se representa , el atributo onclick del botón se ve así:

onclick="this.disabled=true; setTimeout('enableBack()', 3000); 
    WebForm_DoPostBackWithOptions(new 
    WebForm_PostBackOptions('yourControlsName', '', true, '', '', false, true)) 

Y el "enableBack()' función de JavaScript se parece a esto:

function enableBack() 
{ 
    document.getElementById('yourControlsName').disabled=false; 
} 

Así que cuando se hace clic en el botón, se incapacita durante 3 segundos. Si el formulario se publica correctamente, nunca verá el botón volver a habilitar. Sin embargo, si los validadores fallan, el botón vuelve a habilitarse después de 3 segundos.

Todo esto simplemente estableciendo un atributo en el botón - no es necesario escribir un código de JavaScript a mano.

+0

Eso sería genial, pero no existe en mi versión de ASP.NET. ¿¡Qué versión estás usando!? – MGOwen

+0

Estaba usando la última versión en ese momento: Visual Studio 2008. Ya no trabajo para ese empleador, por lo que no puedo verificar nada más (service packs, .NET runtime version, etc.). ¡Disculpe la demora en responder! –

+1

Ahora que lo pienso, creo que la página hizo uso de AJAX, por lo que puede haber sido una extensión proporcionada por el kit de herramientas. –

0

Tenga en cuenta que el enfoque de rp enviará dos veces su formulario si está utilizando botones con UseSubmitBehavior="false".

utilizo la siguiente variación del código de RP:

public static void DisableButtonOnClick(Button button, string clientFunction) 
{ 
    // If the page has ASP.NET validators on it, this code ensures the 
    // page validates before continuing. 
    string script = "if (typeof(Page_ClientValidate) == 'function') { " 
      + "if (!Page_ClientValidate()) { return false; } } "; 

    // disable the button 
    script += "this.disabled = true; "; 

    // If a secondary JavaScript function has been provided, and if it can be found, call it. 
    // Note the name of the JavaScript function to call should be passed without parens. 
    if (!string.IsNullOrEmpty(clientFunction)) 
     script += string.Format("if (typeof({0}) == 'function') {{ {0}() }} ", clientFunction); 

    // only need to post back if button is using submit behaviour 
    if (button.UseSubmitBehavior) 
     script += button.Page.GetPostBackEventReference(button) + "; "; 

    button.Attributes.Add("onclick", script); 
} 
0

La forma correcta (en lo que se refiere a la facilidad de uso, por lo menos) sería deshabilitar el botón con el atributo OnClientClick, realice el cliente junto a la validación, y luego use el resultado de eso para continuar o volver a habilitar el botón.

Por supuesto, TAMBIÉN DEBE escribir el código del lado del servidor para esto, ya que no puede confiar en que la validación se lleve a cabo debido a una falta o implementación particular de JavaScript. Sin embargo, si confía en que el servidor controle el estado habilitado/deshabilitado del botón, básicamente no tendrá forma de bloquear al usuario que envía el formulario varias veces de todos modos. Por esta razón, debe tener algún tipo de lógica para detectar múltiples envíos del mismo usuario en un corto período de tiempo (valores idénticos de la misma sesión, por ejemplo).

0

uno de mi solución es la siguiente:

añadir la secuencia de comandos en el Page_Load de su archivo aspx

HtmlGenericControl includeMyJava = new HtmlGenericControl("script"); 
    includeMyJava.Attributes.Add("type", "text/javascript"); 
    includeMyJava.InnerHtml = "\nfunction dsbButton(button) {"; 
    includeMyJava.InnerHtml += "\nPage_ClientValidate();"; 
    includeMyJava.InnerHtml += "\nif(Page_IsValid)"; 
    includeMyJava.InnerHtml += "\n{"; 
    includeMyJava.InnerHtml += "\nbutton.disabled = true;"; 
    includeMyJava.InnerHtml += "}"; 
    includeMyJava.InnerHtml += "\n}"; 
    this.Page.Header.Controls.Add(includeMyJava); 

y luego ajustar sus parámetros del botón aspx de la siguiente manera:

<asp:Button ID="send" runat="server" UseSubmitBehavior="false" OnClientClick="dsbButton(this);" Text="Send" OnClick="send_Click" /> 

Tenga en cuenta que "onClientClick" ayuda a deshabilitar el botón y "UseSubmitBehaviour" deshabilita el comportamiento de envío tradicional de la página y permite que asp.net muestre el comportamiento de envío al usuario guión

buena suerte

-Waqas Aslam

0

Así que simplemente deshabilitar el botón a través de JavaScript no es una opción compatible entre navegadores.Chrome no envía el formulario si usted sólo tiene que utilizar OnClientClick="this.disabled=true;"
A continuación se muestra una solución que he probado en Firefox 9, Internet Explorer 9 y Chrome 16:

<script type="text/javascript"> 
var buttonToDisable; 
function disableButton(sender) 
{ 
    buttonToDisable=sender; 
    setTimeout('if(Page_IsValid==true)buttonToDisable.disabled=true;', 10); 
} 
</script> 

a continuación, registrar 'disableButton' con el evento de clic de el botón de formulario de presentación, de una manera ser:

<asp:Button runat="server" ID="btnSubmit" Text="Submit" OnClientClick="disableButton(this);" /> 

a tener en cuenta que esto se pone alrededor de su tema del botón está desactivado si falla la validación del lado del cliente. Tampoco requiere procesamiento en el lado del servidor. .

0

Sobre la base @ rp de respuesta, lo modificó para invocar la función personalizada y, o bien presentar y desactivar el éxito o el "alto" en caso de error:

public static void DisableButtonOnClick(Button ButtonControl, string ClientFunction) 
{ 
    StringBuilder sb = new StringBuilder(128); 

    if (!String.IsNullOrEmpty(ClientFunction)) 
    { 
     sb.AppendFormat("if (typeof({0}) == 'function') {{ if ({0}()) {{ {1}; this.disabled=true; return true; }} else {{ return false; }} }};", ClientFunction, ButtonControl.Page.ClientScript.GetPostBackEventReference(ButtonControl, null)); 
    } 
    else 
    { 
     sb.Append("return true;"); 
    } 

    ButtonControl.Attributes.Add("onclick", sb.ToString()); 
} 
Cuestiones relacionadas