Pregunta

Tengo un botón que me gustaría deshabilitar cuando el formulario se envía para evitar que el usuario envíe múltiples veces.

He intentado ingenuamente deshabilitar el botón con javascript onclick pero entonces, si un cliente de la validación del lado del que falla el botón permanece deshabilitado.

¿Cómo desactivar el botón cuando el formulario se envíe con éxito no sólo cuando el usuario hace clic?

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

¿Fue útil?

Solución

Dar a este 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() );
    }
}

Otros consejos

Yo no soy un gran fan de la escritura de todos los que javascript en el código subyacente.Aquí es lo que mi solución final parece.

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>

La siguiente función es útil sin necesidad de la desactivación de la parte que tiende a ser poco fiables.Sólo el uso de "volver check_submit();" como parte de la onclick de los botones de envío.

También debe ser un campo oculto para mantener la form_submitted valor inicial 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;
    }

Deshabilitar el botón en el extremo de su controlador de envío.Si la validación falla, debe devolver false antes de que.

Sin embargo, el código JavaScript enfoque no es algo que se puede confiar, así que usted debe tener algo para detectar duplicados en el servidor.

si la validación es correcta, a continuación, deshabilitar el botón.si no, 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>

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


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

No sólo evitar la doble presentación, pero es un claro indicador para el usuario que no desea que el botón se pulsa más de una vez.

No estoy seguro si esto va a ayudar, pero no hay evento onsubmit en forma.Este evento se puede utilizar siempre que el formulario de envío (desde cualquier botón o controles).Para la referencia: http://www.htmlcodetutorial.com/forms/_FORM_onSubmit.html

Una solución será la de establecer un campo oculto cuando se pulsa el botón, con el número 1.

En el botón haga clic en controlador primero es verificar que el número si es algo distinto de 1 solo de retorno de la función.

Usted también puede ser capaz de tomar ventaja de la onsubmit() de javascript evento que está disponible en los formularios.Este evento se desencadena cuando el formulario es en realidad presentar y que no debería trampa hasta después de la validación es completa.

Esta es una fácil, pero en método similar de lo que rp se 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" />

Tenga en cuenta que la rp del enfoque de doble presentar su formulario si usted está utilizando los botones con UseSubmitBehavior="false".

Yo uso la siguiente variación de rp del código:

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);
}

La correcta (en cuanto a facilidad de uso se refiere, al menos) sería deshabilitar el botón usando el OnClientClick atributo, realizar la validación en el cliente y, a continuación, utilizar el resultado de que para continuar o volver a habilitar el botón.

Por supuesto, usted TAMBIÉN debe escribir el código del lado del servidor para esto, como no se puede confiar en la validación incluso ser llevado a cabo debido a una falta, o de implementación en particular, de JavaScript.Sin embargo, si usted confía en el servidor de control el botón de activado / desactivado de estado, luego de que, básicamente, no tienen manera de bloquear al usuario enviar el formulario varias veces de todos modos.Por esta razón, usted debe tener algún tipo de lógica para la detección de múltiples presentaciones de un mismo usuario en un corto período de tiempo (valores idénticos de la misma Sesión, por ejemplo).

uno de mi solución es como sigue:

agregar 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, a continuación, establezca su aspx botón de parámetros como sigue:

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

Tenga en cuenta que "onClientClick" ayuda a desactivar los botones y "UseSubmitBehaviour", se desactiva la tradicional presentación de comportamiento de la página y permite asp.net para representar el presentar el comportamiento del usuario de secuencia de comandos.

buena suerte

-Waqas Aslam

Escuchado acerca de la "DisableOnSubmit" de propiedad de un <asp:Button>, así:

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

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

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

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

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

Así que, cuando se pulsa el botón, se convierte en movilidad durante 3 segundos.Si el formulario de puestos correctamente, a continuación, usted nunca verá el botón volver a habilitar.Si, sin embargo, validadores fallar, a continuación, el botón se activa de nuevo después de 3 segundos.

Todo esto sólo por el establecimiento de un atributo en el botón--no javascript el código debe ser escrito a mano.

Así que simplemente deshabilitar el botón a través de javascript no es un cross-browser compatible opción.Chrome no presentar el formulario si usted sólo tiene que utilizar OnClientClick="this.disabled=true;"
A continuación es una solución que he probado en Firefox 9, Internet Explorer 9 y google 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 click del formulario de presentación de botón, una manera de ser:

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

Vale la pena señalar que esto se pone alrededor de la cuestión de que el botón está deshabilitado si falla la validación del lado del cliente.También no requiere procesamiento del lado del servidor.

Edificio en @rp.'s respuesta, la he modificado para invocar la función personalizada y presentar y desactivar en el éxito o el "detener" 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());
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top