如何阻止用户单击按钮两次?

时间:2011-05-26 10:34:38

标签: asp.net webforms

我有一个旧的ASP.NET Web表单应用程序(.NET 2.0),其过程在单击按钮时需要30秒左右才能运行。我需要阻止按钮被点击两次。这将阻止发布两次,这会导致数据库中出现重复数据。

我尝试添加;

OnClientClick="this.disabled='true';"

尝试在JavaScript中禁用该按钮。但是,虽然该按钮被禁用,但该按钮的回发不起作用。

禁用该按钮以防止多次提交是此应用程序的理想选择。我怎么能这样做?

修改

我无法使用第三方控件。

14 个答案:

答案 0 :(得分:76)

如果您只是禁用该按钮,那么ASP.NET将不会发布该表单。您还想处理客户端验证。这是我的解决方案:

<asp:Button runat="server" ID="btnSave" 
   Text="Save" OnClick="btnSave_Click" 
   OnClientClick="if (!Page_ClientValidate()){ return false; } this.disabled = true; this.value = 'Saving...';" 
   UseSubmitBehavior="false" />

有关UseSubmitBehavior的说明,请参阅@Dave Ward's post

如果您有多个验证组,则需要为此增强此解决方案。

答案 1 :(得分:24)

答案 2 :(得分:15)

您还需要set the Button's UseSubmitBehavior property to false

Web浏览器不会在表单的POST数据中包含已禁用的元素,即使该元素恰好是首先触发表单提交的按钮。不幸的是,ASP.NET WebForms的单表单页面设计依赖于那些信息来知道哪个控件引发了PostBack以及执行哪个事件处理程序(即Button1.On_Click)。

切换到UseSubmitBehavior="false"会在客户端onclick处理程序中注入__doPostBack('Button1', '')以解决该问题。然后,即使您禁用了Button,__doPostBack参数也允许ASP.NET知道哪个控件引发了PostBack以及哪些事件将在服务器端触发。

答案 3 :(得分:12)

上面提供的大部分解决方案都表明,由于您无法获得PostBack,因此禁用功能无法正常工作。这是我见过的最简单,最干净的工作解决方案:

OnClientClick="if(this.value === 'Saving...') { return false; } else { this.value = 'Saving...'; }"

答案 4 :(得分:8)

为规避所有验证和验证组问题,我发现使用window.onbeforeunload事件最简单,就像这样

<script type = "text/javascript">
function DisableButton() {
    document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>

一旦页面准备好进行包括验证的PostBack或提交ASP.Net表单,上面的脚本就会禁用ASP.Net按钮。

Disable ASP.Net button after click to prevent double clicking

答案 5 :(得分:3)

我发现该链接对解决此问题非常有用 Disable ASP.Net button after click to prevent double clicking

我希望可以提供帮助:)

答案 6 :(得分:2)

我通常会将此方法添加到我的BasePage以供重用。

此代码也处理验证

/// <summary>
///  Avoid multiple submit
/// </summary>
/// <param name="button">The button.</param>
/// <param name="text">text displayed on button</param>
public void AvoidMultipleSubmit(Button button,string text="wait..." )
{
    Page.ClientScript.RegisterOnSubmitStatement(GetType(), "ServerForm", "if(this.submitted) return false; this.submitted = true;");
    button.Attributes.Add("onclick", string.Format("if(typeof(Page_ClientValidate)=='function' && !Page_ClientValidate()){{return true;}}this.value='{1}';this.disabled=true;{0}",
        ClientScript.GetPostBackEventReference(button, string.Empty),text));
}

答案 7 :(得分:1)

优点

  • 开箱即用,适用于所有按钮
    • 即使未触发提交的按钮也将被停用。
    • LinkBut​​tons也将被禁用。
  • 使用UpdatePanels(即部分和异步回发)
  • 适用于完整的回发
  • 验证阻止回发时不会禁用按钮
  • 按下按钮,按下Enter键和AutoPostBack事件将导致按钮被禁用

限制

†我见过的大多数其他解决方案都有这些相同的限制

  • 依赖于jQuery
  • 仅适用于ASP表单
  • 如果用户在提交后点击浏览器的取消按钮,则用户将无法再次提交,可能会感到困惑。
  • 还有其他方式可以让用户发起回发:
    • 使用回车键提交
    • 自动回溯事件

代码

只需在结束</body>代码之前将此代码段放在HTML代码的底部。

<script type="text/javascript">
    jQuery(function ($) {

        /*
         * Prevent Double Submit
         * ---------------------
         * Disables submit buttons during form submission and asp async postbacks
         */

        // class name assigned to disabled :submit elements
        var disabledClass = 'asp-postback-disable';

        // selector for buttons and other elements that may cause a postback
        var submittableSelector = [
            'a[href^="javascript:__doPostBack"]',
            ':submit'
        ].join(",");

        // returns false; used to prevent event bubbling
        function returnFalse() { return false; }

        // logs errors
        function error(ex) {
            if (typeof console === 'object' && console.error != null) {
                console.error('Prevent Double Submit Error:', ex);
            }
        }

        // disables :submit elements
        function disableSubmit() {
            try {
                $(submittableSelector, 'form')
                    .addClass(disabledClass)
                    .on('click.asp-postback-disable', returnFalse);
            }
            catch (ex) { error(ex); }
        }

        // enables :submit elements
        function enableSubmit() {
            try {
                $('.asp-postback-disable,' + submittableSelector, 'form')
                    .removeClass(disabledClass)
                    .off('click.asp-postback-disable', returnFalse);
            }
            catch (ex) { error(ex); }
        }

        // Handle async postbacks
        if (typeof Sys === 'object') {
            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_beginRequest(function (s, e) { disableSubmit(); });
            prm.add_endRequest(function (s, e) { enableSubmit(); });
        }
        else {
            error('Sys is undefined.');
        }

        // Handle navigation (eg, Full postback)
        $(window).bind('beforeunload', function (e) {
            disableSubmit();
        });

    });
</script>

<style type="text/css">
    .asp-postback-disable { opacity: 0.25; }
</style>

答案 8 :(得分:0)

您可以做的一件事就是点击后将其隐藏在客户端并显示一些加载器图像。

或者,如果是表格或其他内容,您可以添加recaptcha

答案 9 :(得分:0)

经过一段时间的搜索,我想出了这个解决方案。

$('form').submit(function () {
    $('input[type=submit][data-loading]').addClass('disabled');

    if ($(this).data('submitted') == true) {
        $('input[type=submit][data-loading]').attr('disabled', 'disabled');
        return false;
    }

    $(this).data('submitted', true);
});

UseDefaultBehavior解决方案的问题是Enter键停止不提交经常使用的表单。我假设相当比例的用户尝试输入而不是点击。

答案 10 :(得分:0)

从aspx.cs文件中,您可以添加脚本来解决此问题(这是唯一适用于我的解决方案,由以下人员提供:wexxix)

//Declaring the string to hold the script
string doubleClickScript = @"<script type='text/javascript'>
                                    function DisableButton() {
                                    document.getElementById('YOURBUTTONID').disabled = true;
                                }
                                window.onbeforeunload = DisableButton;
                                </script>";
//Injecting the script to the aspx page.        
ClientScript.RegisterStartupScript(this.GetType(), "DoubleClickScript", doubleClickScript);

显然你可以将脚本添加到页面中,我只是这样使用,因为我只能访问客户的C#代码。 感谢

答案 11 :(得分:0)

您还可以通过创建具有相同样式的客户端按钮,隐藏“原始”服务器端按钮并使用javascript禁用HTML按钮/调用原始按钮来单击来“破解”它。 / p>

在下一次回发中,它将自动还原对客户端按钮:)的更改。

<asp:Button ID="btnSubmitQuote" class="btn btn-red btn-block" runat="server" Text="Submit Quote" style="display:none;" OnClick="btnSubmitQuote_Click" UseSubmitBehavior="false" />

<button id="btnSubmitQuoteClient"  class="btn btn-red btn-block" onclick ="disableBtn(this);">Submit Quote</button>
<script type="text/javascript">
 function disableBtn(t) {
    t.setAttribute('disabled', 'disabled');
    var btn = document.getElementById('<%=btnSubmitQuote.ClientID %>');
    btn.click();
  }

答案 12 :(得分:0)

在表单的Page_Load事件中,输入以下行:

btnSubmit.Attributes.Add("onclick", " this.disabled = true; " + ClientScript.GetPostBackEventReference(btnSubmit, null) + ";");

来源:dotnetodyssey.com

答案 13 :(得分:-3)

这是一个快速解决方案。单击它时将宽度设置为0。它仍然会提交,但他们将无法再次点击它。如果要在存在验证错误的情况下再次显示它,则可以在服务器端单击事件上将宽度设置回原始值。

OnClientClick="this.width=0;"