【问题标题】:Disable Submit button in case of multiple click.. (C#)在多次单击的情况下禁用提交按钮.. (C#)
【发布时间】:2011-05-19 16:01:29
【问题描述】:

我的问题是,我有一个简单的 Web 表单,其中包含两个文本框和一个按钮。页面上有一些 asp.net 验证器控件。所以我希望在完成所有验证后客户端禁用按钮。禁用按钮,我正在执行一些服务器端代码。所有这些都工作正常,但是,如果我设置按钮的回发 url,它会失败。下面是编码的一部分,它会给你一些简要的想法。任何提示将不胜感激.......

我想在复合控件中实现此功能。 这是按钮类

public class MyButton : Button
{

    protected override void OnPreRender(EventArgs e)
    {
        if (this.CausesValidation)
        {
            if (!String.IsNullOrEmpty(this.ValidationGroup))
            {
                this.Attributes.Add("onclick", @"javascript:

             if (typeof(Page_ClientValidate) == 'function')
                 {
                    if (Page_ClientValidate('" + this.ValidationGroup + "')){" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) +

              "}else{return;}}  else{" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) + "}");
            }

            else
            {
                this.Attributes.Add("onclick", @"javascript:

                 if (typeof(Page_ClientValidate) == 'function')
                   {
                      if (Page_ClientValidate()){" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) +
                  "}else{return;}}  else{" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this) + "}");
            }
        }
        else
            this.Attributes.Add("onclick", "javascript:" + this.ClientID + ".disabled=true;" + Page.GetPostBackEventReference(this));

        base.OnPreRender(e);
    }

【问题讨论】:

  • 所有这些解决方案都存在一个问题,如果在系统缓慢时单击按钮的速度足够快,则可以将第二次推送排队并再次调用 on-click 方法,即使第一次点击禁用按钮。

标签: c# asp.net button


【解决方案1】:

这是正确且简单的方法:

在您的应用程序中创建一个辅助方法(例如在 Utlity 命名空间中):

    Public Shared Sub PreventMultipleClicks(ByRef button As System.Web.UI.WebControls.Button)
        button.Attributes.Add("onclick", "this.disabled=true;" & button.Page.ClientScript.GetPostBackEventReference(button, String.Empty).ToString)
    End Sub

现在您可以从每个网页背后的代码中调用:

    Utility.PreventMultipleClicks(button1)

其中 button1 是您要防止多次点击的按钮。

这只是将点击处理程序设置为:this.disabled=true

然后附加按钮自己的回发处理程序,所以我们得到:

onclick="this.disabled=true";__doPostBack('ID$ID','');"

这不会破坏页面的默认行为,并且可以在所有浏览器中按预期工作。

享受吧!

【讨论】:

  • 感谢您的回答。效果很好。我通过扩展方法与实用程序/帮助程序创建了相同的解决方案,但效果很好。
  • 我在这上面浪费了几个小时——谢谢你的回答。我对你的答案投了赞成票,我希望 O.P. 有一天会接受它。
  • 这确实破坏了默认行为;当 ASP.NET 验证失败时,它仍然回发并禁用按钮。
  • 我有一个链接按钮,只是将脚本修改为:button.Attributes.Add("onclick", "if(this.disabled) return false; this.disabled=true;"...
【解决方案2】:

如果您禁用该按钮,则不会发生表单提交。正确的方法是设置计时器以禁用按钮。我还建议使用提交行为而不是放置回发事件参考。例如,

function clickHandler(id, validate, validationGroup) {
   var isValid = true;
   if (validate && typeof(Page_ClientValidate) == 'function') {
     isValid = validationGroup? Page_ClientValidate(validationGroup): Page_ClientValidate();
   }
   if (isValid)
   {
      // set timer to disable the button
      var b = document.getElementById(id);
      var f = function() { b.disabled = 'disabled'; };
      setTimeout(f, 100);
      return true;
   }
   return false;
}

现在将功能附加到您的按钮

protected override void OnPreRender(EventArgs e)
{
    this.Attributes.Add("onclick", 
       string.Format("return clickHandler('{0}', {1}, '{2}')", 
       this.ClientID, this.CausesValidation ? "true" : "false", 
       this.ValidationGroup));
}

【讨论】:

  • 第一个函数是Javascript还是C#?
【解决方案3】:

如果您在单击提交按钮后禁用它,则它不会回发。我已经研究这个很多小时了,the best solution I've seen is here(最好的解决方案在页面底部)

我现在正在编写一个自定义服务器控件以添加到从 Button 扩展的工具箱中,并使用此代码的略微修改版本。 (重写 OnLoad 方法)

我允许用户将“处理...”文本更改为其他内容,并且可以创建一个属性,允许在提交完成时将文本更改为其他内容(这将在回发时产生返回)

【讨论】:

    【解决方案4】:

    我想出了解决方案。只需在单击后隐藏按钮即可。回发将照常进行。回发完成后,您将按原样获得按钮!详细步骤见how to disable asp.net button on postback,掌握艺术!

    【讨论】:

      【解决方案5】:

      假设这是异步的,并且您在保存之前进行了验证,您可以尝试伪跟随:

          bool hasSavedAlready = false;
      
          savedata(){
             if (!hasSavedAlready){ 
             //normal saving code
             ...
             //after success
             hasSavedAlready = true;
      
             }
          }
      

      这是我能想到的最简单的解决方案。

      【讨论】:

        【解决方案6】:

        我遇到了这个问题,以前的解决方案都不适合我,但经过一番折腾后,我使用了:

        <asp:LinkButton runat="server" OnClientClick="this.setAttribute('disabled','disabled'); this.text = 'Submit in progress...';" UseSubmitBehavior="false" ID="btnSubmit" ValidationGroup="formSubmit"</asp:LinkButton>
        

        【讨论】:

          【解决方案7】:

          您需要考虑,如果同一个会话/用户在窗口或选项卡上打开一个页面(example.whatever)让我们说 window1,然后他再次打开同一个页面(example.whatever)在 window2 上。

          当用户单击 window1 上的按钮并在 30 秒结束前单击 window2 上的该按钮时,服务器会认为您单击了该按钮两次。

          为了避免在 asp.net 中出现这种情况,我使用:

          Application["isButtonGettingClickedByAnyOne"]这是一个在所有会话(您网站的所有用户)之间共享的数组。

          Session["isButtonGettingClickedByThisUserInAnotherTab"] 您可以将其视为在所有选项卡(同一用户的)之间共享。

          并让服务器检查它们是否被某些人保留。

          • 如果然后等待30秒 +你转...
          • 如果那么你可以先保留它,然后执行你的函数,当你完成函数释放它 以便其他人可以再次使用它。

          我希望这很有用,而且阅读起来并不痛苦。

          【讨论】:

            猜你喜欢
            • 2013-12-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-04
            • 1970-01-01
            • 2020-08-14
            相关资源
            最近更新 更多