表单提交时禁用按钮

时间:2008-09-20 00:09:30

标签: asp.net javascript webforms

我有一个按钮,我希望在表单提交时禁用,以防止用户多次提交。

我已尝试使用javascript onclick天真地禁用该按钮,但如果客户端验证失败,则该按钮将保持禁用状态。

当表单成功提交时,如何在用户单击时单击?

时禁用该按钮

这是一个ASP.NET表单,所以我想尽可能与asp.net ajax页面生命周期挂钩。

17 个答案:

答案 0 :(得分:17)

我不是在代码隐藏中编写所有javascript的忠实粉丝。这是我的最终解决方案。

按钮:

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

答案 1 :(得分:14)

给它一个旋转:

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

答案 2 :(得分:5)

以下功能非常有用,无需使用往往不可靠的禁用部分。只需使用“return check_submit();”作为提交按钮的onclick处理程序的一部分。

还应该有一个隐藏字段来保存form_submitted的初始值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;
    }

答案 3 :(得分:2)

禁用提交处理程序最末端的按钮。如果验证失败,则应在此之前返回false。

但是,JavaScript方法不是可以依赖的东西,所以你应该有一些东西来检测服务器上的重复项。

答案 4 :(得分:2)

如果验证成功,则禁用该按钮。如果不是,那就不要了。

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

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

答案 5 :(得分:1)

将按钮上的可见性设置为“无”;


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

它不仅可以防止双重提交,而且还可以清楚地指示用户您不希望多次按下该按钮。

答案 6 :(得分:0)

在我们的遗留应用程序中遇到了rp的代码,该应用程序正处于一些疯狂的行为中。

将其追溯到一个奇怪的事件触发组合-在UpdatePanel中的asp按钮上使用DisableButtonOnClick()时,POST将发送两次(一次由DisableButtonOnClick()添加的doPostBack,一次由UpdatePanel)。但是,这仅在某些浏览器中发生(Edge的早期版本,而不是最近的版本,而IE11做到了,Chrome和FireFox却没有(至少我测试过的版本))。我认为Chrome和Edge的较新版本正在内部以某种方式处理这种情况。使用IE中的F12 devtools跟踪问题-两次POST发生得非常紧密,以至于第一个POST立即中止,但是在某些情况下(网络延迟,用户计算机负载等),请求的确会在浏览器可以访问之前到达服务器中止。因此,这导致整个系统中的按钮按下都产生了看似随机的双重作用,而且追溯起来很痛苦。解决方法是添加“ return false”;在doPostBack之后,以防止在运行旧版本的浏览器时涉及UpdatePanel。

TLDR-在updatepanels中的按钮上提防此代码。这是一个好方法,也很不错,但是在我(可能是边缘)的情况下有潜在的问题。

ps-我会对rp的帖子发表评论,但我没有代表。认为这可能对将来的旅行者有用。

答案 7 :(得分:0)

在@rp。的答案的基础上,我修改了它以调用自定义函数,并在成功时提交和禁用或者停止&#34;出错:

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

答案 8 :(得分:0)

所以简单地通过javascript禁用按钮不是跨浏览器兼容的选项。如果您只使用OnClientClick="this.disabled=true;",则Chrome不会提交表单 以下是我在Firefox 9,Internet Explorer 9和Chrome 16中测试过的解决方案:

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

然后使用表单提交按钮的click事件注册'disableButton',其中一种方式是:

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

值得注意的是,如果客户端验证失败,这会解决您的按钮被禁用的问题。也不需要服务器端处理。

答案 9 :(得分:0)

我的解决方案之一如下:

在aspx文件的page_load中添加脚本

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

然后设置您的aspx按钮参数如下:

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

请注意,“onClientClick”有助于禁用按钮,“UseSubmitBehaviour”禁用页面的传统提交行为,并允许asp.net根据用户脚本呈现提交行为。

祝你好运

-Waqas Aslam

答案 10 :(得分:0)

正确(就用户友好性而言,至少)方式是使用OnClientClick属性禁用按钮,执行客户端验证,然后使用其结果继续或重新启用按钮。

当然,您应该为此编写服务器端代码,因为由于JavaScript的缺乏或特定实现,您无法依赖验证。但是,如果您依赖服务器控制按钮的启用/禁用状态,那么您基本上无法阻止用户多次提交表单。出于这个原因,您应该有一些逻辑来检测来自同一用户的短时间内的多个提交(例如,来自同一会话的相同值)。

答案 11 :(得分:0)

请注意,如果您使用UseSubmitBehavior="false"按钮,则rp的方法会双重提交您的表单。

我使用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);
}

答案 12 :(得分:0)

刚刚听说过&lt; asp:Button&gt;的“DisableOnSubmit”属性,如下所示:

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

渲染时,按钮的onclick属性如下所示:

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

“enableBack()”javascript函数如下所示:

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

因此,当单击该按钮时,它将被禁用3秒钟。如果表单成功发布,那么您永远不会看到该按钮重新启用。但是,如果任何验证器失败,则按钮将在3秒后再次启用。

所有这一切只需在按钮上设置属性 - 不需要手工编写javascript代码。

答案 13 :(得分:0)

这是一种比rp建议更容易但更相似的方法:

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" />

答案 14 :(得分:0)

您也可以利用表单上提供的onsubmit()javascript事件。当表单实际提交时,此事件将触发,并且在验证完成之前不应该陷阱。

答案 15 :(得分:0)

解决方案是在单击按钮时设置隐藏字段,编号为1.

在按钮单击处理程序上,首先要检查该数字是否为1以外的其他内容只是退出该函数。

答案 16 :(得分:0)

不确定这是否有帮助,但是在表单中有提交事件。只要表单提交(从任何按钮或控件),您就可以使用此事件。 供参考:http://www.htmlcodetutorial.com/forms/_FORM_onSubmit.html