Почему моя форма не публикуется, когда я отключаю кнопку отправки, чтобы предотвратить двойное нажатие?
-
03-07-2019 - |
Вопрос
Как и у любого другого веб-разработчика на планете, у меня возникает проблема с пользователями, которые дважды нажимают кнопку отправки в моих формах.Насколько я понимаю, обычный способ решения этой проблемы — отключить кнопку сразу после первого нажатия, однако когда я это делаю, оно не публикует.
Я провел небольшое исследование по этому поводу, видит бог, информации достаточно, но есть и другие вопросы, такие как Отключить кнопку при отправке формы, отключение кнопки, похоже, работает.Оригинальный постер Отключить кнопку после отправки Похоже, у него была та же проблема, что и у меня, но нет никаких упоминаний о том, как/если он ее решил.
Вот код, как это повторить (протестировано в 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;
}
А что поставить вместо кнопки?
- Либо изображение, похожее на отключенную кнопку
- Или просто текст с надписью «Пожалуйста, подождите…».
И это можно сделать так же, но в обратном порядке.Начните с того, что элемент скрывается при загрузке страницы, а затем переключитесь на видимое имя класса при отправке формы.
Мы используем следующий скрипт 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»