Как запретить пользователям дважды щелкнуть кнопку?

У меня есть старое приложение ASP.NET для веб-форм (.NET 2.0), у которого есть процесс, который занимает 30 секунд или около того, чтобы запускаться при нажатии кнопки. Мне нужно, чтобы кнопка не была дважды нажата. Это предотвратит отправку сообщений дважды, что приведет к дублированию данных в базе данных.

Я попробовал добавить:

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

чтобы попытаться отключить кнопку в JavaScript. Однако, хотя кнопка становится отключенной, обратная передача для кнопки тогда не работает.

Отключение кнопки для предотвращения нескольких представлений является идеальным для этого приложения. Как я могу это сделать?

ИЗМЕНИТЬ

Я не могу использовать сторонние элементы управления.

Ответ 1

Вы должны вернуть true после OnClientClick:

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

Любые клики на стороне клиента должны возвращать значение true, если последующая обратная связь должна продолжаться, это средство обеспечения клиентской стороны validatin при нажатии кнопок.

Ответ 2

Если вы просто отключите кнопку, то 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" />

См. @Сообщение Dave Ward для описания UseSubmitBehavior.

Если у вас несколько групп проверки, вам нужно будет улучшить это решение.

Ответ 3

Вам также нужно установить для свойства Button UseSubmitBehavior значение false.

Веб-браузеры не включают отключенные элементы в форме POST-данных, даже если элемент является кнопкой, которая инициировала отправку формы в первую очередь. К сожалению, дизайн одноформатной страницы ASP.NET WebForms основывается на этом бите информации, чтобы знать, какой элемент управления поднял PostBack и какой обработчик события выполнить (т.е. Button1.On_Click).

Переключение на UseSubmitBehavior="false" вставляет __doPostBack('Button1', '') в обработчик onclick на стороне клиента, чтобы обойти эту проблему. Затем, даже если вы отключите кнопку, параметр __doPostBack позволяет ASP.NET знать, какой элемент управления поднял PostBack и какие события запускаться на стороне сервера.

Ответ 4

Большинство этих решений, приведенных выше, показывают, что отключение не будет работать, потому что вы не получите PostBack. Это самое простое и чистое решение для работы, которое я видел:

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

Ответ 5

Чтобы обойти все проблемы проверки и группы проверки, я нашел, что проще всего использовать событие window.onbeforeunload, например

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

Приведенный выше скрипт отключает кнопку ASP.Net, как только страница готова выполнить PostBack, включая проверку или отправку формы ASP.Net.

Отключить кнопку ASP.Net после нажатия, чтобы предотвратить двойной щелчок

Ответ 6

Вы можете использовать PostBack Ritalin. PostBack Ritalin - это серверный элемент управления ASP.NET AJAX, который упрощает общую задачу отключения кнопок во время частичных обратных передач.

Ответ 8

Я обычно добавляю этот метод в мой 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));
}

Ответ 9

Преимущества

  • Работает со всеми кнопками
    • Даже кнопки, которые не запускают отправку, будут отключены.
    • LinkButtons также будет отключен.
  • Работает с UpdatePanels (т.е. частичные и асинхронные обратные передачи)
  • Работает для полных postbacks
  • Не будет отключать кнопки, если проверка не предотвратит обратную передачу
  • Нажмите кнопку, нажмите клавишу ввода и события AutoPostBack вызовут блокировку кнопок.

Ограничения

† Большинство других решений, которые я видел, имеют те же ограничения

  • Опирается на jQuery
  • † Работает только для форм ASP
  • † Если пользователь нажимает кнопку отмены браузера после отправки, пользователь не сможет снова отправить сообщение и может запутаться.
  • † Остаются другие способы, с помощью которых пользователь мог инициировать обратную передачу:
    • Отправить с помощью клавиши ввода
    • События Autopostback

код

Просто разместите этот фрагмент внизу кода HTML до закрытия тега </body>.

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

Ответ 10

Одна вещь, которую вы можете сделать, - это щелкнуть ее, скрыть ее на стороне клиента и показать некоторые изображения загрузчика.

Или если его форму или что-то можно добавить recaptcha

Ответ 11

После поиска какое-то время я придумал это решение.

$('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 перестает подавать форму, которая используется много. Я предполагаю, что значительный процент пользователей пытается ввести вместо нажатия.

Ответ 12

Вы также можете скрыть кнопку или изменить ее для загрузки изображения, чтобы сохранить обратную связь

$(document).on('submit','form',function (e) {
    $("input.SubmitButton").hide();
    // or change if to an loading gif image.
    return true;
});

Ответ 13

Из файла aspx.cs вы можете добавить script для его адресации (это единственное решение, с которым я работал, и был предоставлен: 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);

Очевидно, вы можете просто добавить script на страницу, я просто так использовал, так как у меня только что был доступ к коду С# клиента. Благодаря

Ответ 14

Вы также можете "взломать" это путем создания кнопки на стороне клиента с тем же стилем, скрытия "оригинальной" кнопки на стороне сервера и использования javascript для отключения кнопки HTML/вызова исходной кнопки для нажатия.

В следующем постбэке он автоматически отменит ваше изменение на клиентской кнопке :).

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

Ответ 15

Вот быстрое решение. Установите ширину в 0, когда они нажмут на нее. Он все равно будет отправлен, но они не смогут его снова щелкнуть. Если вы хотите снова показать его в сценарии, что есть ошибка проверки, вы можете установить значение Width на исходное значение в событии клика на стороне сервера.

OnClientClick="this.width=0;"