Почему моя форма не публикуется, когда я отключаю кнопку отправки, чтобы предотвратить двойное нажатие?

StackOverflow https://stackoverflow.com/questions/400616

Вопрос

Как и у любого другого веб-разработчика на планете, у меня возникает проблема с пользователями, которые дважды нажимают кнопку отправки в моих формах.Насколько я понимаю, обычный способ решения этой проблемы — отключить кнопку сразу после первого нажатия, однако когда я это делаю, оно не публикует.

Я провел небольшое исследование по этому поводу, видит бог, информации достаточно, но есть и другие вопросы, такие как Отключить кнопку при отправке формы, отключение кнопки, похоже, работает.Оригинальный постер Отключить кнопку после отправки Похоже, у него была та же проблема, что и у меня, но нет никаких упоминаний о том, как/если он ее решил.

Вот код, как это повторить (протестировано в IE8 Beta2, но возникла та же проблема в IE7)

Мой код aspx

<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<script language="javascript" type="text/javascript">
    function btn_onClick()
    {
        var chk = document.getElementById("chk");
        if(chk.checked)
        {
            var btn = document.getElementById("btn");
            btn.disabled = true;
        }
    }
</script>
<body>
    <form id="form1" runat="server">
        <asp:Literal ID="lit" Text="--:--:--" runat="server" />
        <br />
        <asp:Button ID="btn" Text="Submit" runat="server" />
        <br />
        <input type="checkbox" id="chk" />Disable button on first click
    </form>
</body>
</html>

Мой код cs

using System;

public partial class _Default : System.Web.UI.Page 
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        btn.Click += new EventHandler(btn_Click);
        btn.OnClientClick = "btn_onClick();";
    }

    void btn_Click(object sender, EventArgs e)
    {
        lit.Text = DateTime.Now.ToString("HH:mm:ss");
    }
}

Обратите внимание, что при нажатии кнопки происходит обратная передача и время обновляется.Но когда вы устанавливаете флажок, при следующем нажатии кнопки кнопка отключается (как и ожидалось), но обратная передача никогда не выполняется.

ЧЕГО Я ЗДЕСЬ ПРОПАВАЛ???

Заранее спасибо.

Это было полезно?

Решение

Я думаю, вам просто не хватает этого тега:

UseSubmitBehavior="false"

Попробуйте это так:

<asp:Button ID="btnUpdate" runat="server" UseSubmitBehavior="false" OnClientClick="if(Page_ClientValidate()) { this.disabled = true; } else {return false;}" Text = "Update" CssClass="button" OnClick="btnUpdate_Click" ValidationGroup="vgNew"/>

Объяснение

Другие советы

Fall888 прав, ваш подход не работает в разных браузерах.я использую этот маленький фрагмент чтобы предотвратить двойной щелчок.

UseSubmitBehavior="false" преобразует кнопку отправки в обычную кнопку (<input type="button">).Если вы не хотите, чтобы это произошло, вы можете скрыть кнопку отправки и сразу же вставить на ее место отключенную кнопку.Поскольку это происходит так быстро, для пользователя это будет выглядеть как отключение кнопки.Подробности на блог Джоша Стодолы.

Пример кода (jQuery):

$("#<%= btnSubmit.ClientID %>").click(function()
{
  $(this)
    .hide()
    .after('<input type="button" value="Please Wait..." disabled="disabled" />');
});

«Отключение» элементов управления HTML не всегда приводит к единообразному поведению во всех основных браузерах.Поэтому я стараюсь избегать этого на стороне клиента, потому что (при работе с моделью ASP.NET) в этом случае вам необходимо отслеживать состояние элемента на клиенте и сервере.

Я бы переместил кнопку из видимой части окна, переключив имя класса кнопки на класс CSS, который содержит следующее:

.hiddenButton
{
  position: absolute;
  top: -1000px;
  left: -1000px;
}

А что поставить вместо кнопки?

  1. Либо изображение, похожее на отключенную кнопку
  2. Или просто текст с надписью «Пожалуйста, подождите…».

И это можно сделать так же, но в обратном порядке.Начните с того, что элемент скрывается при загрузке страницы, а затем переключитесь на видимое имя класса при отправке формы.

Мы используем следующий скрипт JQuery, чтобы отключить все кнопки (тип ввода = отправить и кнопка), когда одна кнопка нажимается.

Мы только что включили скрипт в глобальный файл JavaScript, поэтому нам не нужно ничего запоминать при создании новых кнопок.

$(document).ready(function() {
    $(":button,:submit").bind("click", function() {
        setTimeout(function() {
            $(":button,:submit").attr("disabled", "true");
        }, 0);
    });
});

Этот сценарий можно легко расширить, проверив Page_ClientValidate().

document.getElementById('form1').onsubmit = function() {
    document.getElementById('btn').disabled = true;
};

Это правильный и простой способ сделать это:

Он работает во всех браузерах (в отличие от принятого решения выше).

Создайте вспомогательный метод в своем приложении (скажем, в пространстве имен утилиты):

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

Теперь из кода каждой вашей веб-страницы вы можете просто вызвать:

    Utility.PreventMultipleClicks(button1, page)

где button1 — это кнопка, на которую вы хотите запретить несколько нажатий.

Это просто устанавливает обработчик щелчка на:this.disabled=истина

а затем добавляет собственный обработчик обратной отправки кнопок, поэтому мы получаем:

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

Это не нарушает поведение страницы по умолчанию и работает во всех браузерах должным образом.

Наслаждаться!

Что произойдет в целях отладки, если вы поместите предложение else в if(chk.checked)?

Убедитесь, что ваша функция javascript возвращает true (или значение, которое будет иметь логическое значение true), иначе форма не будет отправлена.

function btn_click()
var chk = document.getElementById("chk");
    if(chk.checked)
    {
            var btn = document.getElementById("btn");
            btn.disabled = true;
            return true;   //this enables the controls action to propagate
    }
    else    return false;  //this prevents it from propagating
}

ДЛЯ ПОЛЬЗОВАТЕЛЕЙ JQUERY

Вы столкнетесь со всевозможными проблемами, пытаясь добавить JavaScript непосредственно к событию onClick на кнопках ASP.NET при использовании прослушивателей событий jQuery.

Я обнаружил, что лучший способ отключить кнопки и заставить обратную передачу работать — это сделать что-то вроде этого:

    $(buttonID).bind('click', function (e) {

        if (ValidateForm(e)) {

            //client side validation ok!
            //disable the button:
            $(buttonID).attr("disabled", true);

            //force a postback:
            try {
                __doPostBack($(buttonID).attr("name"), "");
                return true;
            } catch (err) {
                return true;
            }

        }
        //client side validation failed!
        return false;
    });

Где Форма проверки — это ваша пользовательская функция проверки, которая возвращает true или false, если ваша форма проверяет клиентскую сторону.

И идентификатор кнопки это идентификатор вашей кнопки, например «#button1»

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top