Отключить кнопку при отправке формы

У меня есть кнопка, которую я хотел бы отключить при отправке формы, чтобы пользователь не отправлял ее несколько раз.

Я попытался наивно отключить кнопку с помощью javascript onclick, но затем, если проверка на стороне клиента не выполняется, кнопка остается отключенной.

Как отключить кнопку, если форма успешно отправляется не только при нажатии пользователем?

Это форма ASP.NET, поэтому я хотел бы, если возможно, хорошо подключиться к жизненному циклу страницы asp.net ajax.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
0
16 034
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Отключите кнопку в самом конце обработчика отправки. Если проверка не удалась, перед этим она должна вернуть false.

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

Не уверен, что это поможет, но в форме есть событие onsubmit. Вы можете использовать это событие всякий раз, когда форма отправляется (с любой кнопки или элементов управления). Для справки: http://www.htmlcodetutorial.com/forms/_FORM_onSubmit.html

Следующая функция полезна без необходимости отключения части, которая имеет тенденцию быть ненадежной. Просто используйте "return check_submit ();" как часть обработчика onclick кнопок отправки.

Также должно быть скрытое поле для хранения начального значения form_submitted, равного 0;

<input type = "hidden" name = "form_submitted" value = "0">

function check_submit (){
            if (document.Form1.form_submitted.value == 1){
                alert("Don't submit twice. Please wait.");
                return false;
            }
            else{
                document.Form1.form_submitted.value = 1;
                return true;
            }
            return false;
    }

Здесь много отличных ответов, но этот красивый.

Sean 12.04.2013 01:29

Решением будет установка скрытого поля при нажатии кнопки с номером 1.

В обработчике нажатия кнопки первое, что нужно сделать, это проверить это число, если это что-то иное, чем 1, просто вернитесь из функции.

Вы также можете воспользоваться событием javascript onsubmit (), которое доступно в формах. Это событие возникает, когда форма действительно отправляется, и не должно прерываться до завершения проверки.

Ответ принят как подходящий

Дайте этому кружку:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

         // Identify button as a "disabled-when-clicked" button...
         WebHelpers.DisableButtonOnClick( buttonTest, "showPleaseWait" ); 
    }

    protected void buttonTest_Click( object sender, EventArgs e )
    {
        // Emulate a server-side process to demo the disabled button during
        // postback.
        Thread.Sleep( 5000 );
    }
}



using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Text;

public class WebHelpers
{
    //
    // Disable button with no secondary JavaScript function call.
    //
    public static void DisableButtonOnClick( Button ButtonControl )
    {
        DisableButtonOnClick( ButtonControl, string.Empty );    
    }

    //
    // Disable button with a JavaScript function call.
    //
    public static void DisableButtonOnClick( Button ButtonControl, string ClientFunction )
    {   
        StringBuilder sb = new StringBuilder( 128 );

        // If the page has ASP.NET validators on it, this code ensures the
        // page validates before continuing.
        sb.Append( "if ( typeof( Page_ClientValidate ) == 'function' ) { " );
        sb.Append( "if ( ! Page_ClientValidate() ) { return false; } } " );

        // Disable this button.
        sb.Append( "this.disabled = true;" ); 

        // If a secondary JavaScript function has been provided, and if it can be found,
        // call it. Note the name of the JavaScript function to call should be passed without
        // parens.
        if ( ! String.IsNullOrEmpty( ClientFunction ) ) 
        {
            sb.AppendFormat( "if ( typeof( {0} ) == 'function' ) {{ {0}() }};", ClientFunction );  
        }

        // GetPostBackEventReference() obtains a reference to a client-side script function 
        // that causes the server to post back to the page (ie this causes the server-side part 
        // of the "click" to be performed).
        sb.Append( ButtonControl.Page.ClientScript.GetPostBackEventReference( ButtonControl ) + ";" );

        // Add the JavaScript created a code to be executed when the button is clicked.
        ButtonControl.Attributes.Add( "onclick", sb.ToString() );
    }
}

рп. одно небольшое изменение, которое мне пришлось сделать, - передать имя моей группы проверки методу Page_ClientValidate (). Спасибо за код!

Brownie 22.09.2008 05:00

Я не злодей ... но писать столько кода вместо onsubmit = "this.button.disable = true" или чего-то подобного в теге <form> - это как-то ... странно? : |

Ionuț Staicu 18.12.2008 23:21

Staicu: ваше решение не принимает во внимание, прошла ли проверка или нет. В вашем решении, если проверка не удалась, кнопка сохранения остается отключенной.

Brownie 16.01.2009 06:31

Кажется, для меня Брауни принимает во внимание валидацию.

Adam Nofsinger 05.03.2009 00:55

Отличный фрагмент кода какое-то время искал что-то подобное

TheAlbear 18.03.2009 19:02

Отличный код, в итоге я сделал его методом расширения для всех своих кнопок. public static void DisableButtonOnClick (эта кнопка ButtonControl, строка ClientFunction)

BigBlondeViking 24.06.2009 22:15

50 строк кода на стороне сервера, необходимых для выполнения тонкости на стороне клиента? Спасибо, не надо!!

Josh Stodola 29.06.2009 18:25

Дай парню передохнуть, Джош: некоторые из этих строк пусты, многие используют операторы и довольно много комментариев! :-)

Steve J 04.11.2009 18:15

Джош. Сейчас, когда я прочно закрепился за jQuery и большим объемом работы на стороне клиента, мой подход теперь может немного отличаться - но только потому, что теперь я меньше привязан к элементам управления на стороне сервера. Тем не менее, если LOC - ваша метрика, покажите мне клиентский код меньшим количеством кода! Обязательно поиграйте с валидаторами ASP.NET и вызовите функцию, если она предусмотрена. (спасибо за защиту, Стив Дж.)

rp. 04.11.2009 21:38

отличная идея, кто-нибудь знает, как я могу добавить в это решение подтверждение возврата ('Вы уверены, что хотите отправить') {// выполнить обработку}?

Welsh King 17.10.2011 12:57

Я нашел этот подход полезным, поскольку класс WebHelper позволяет легко использовать его повторно. Первоначально подход ниже (меньше кода программной части JS) казался приятным и простым, но у меня были проблемы с его проверкой. (Если проверка не удалась, кнопка НЕ ​​вернется в активное состояние надежно.) Таким образом, эта кнопка оказалась победителем. (Особенно, если вы работаете над тяжелым серверным проектом.)

Dylan - INNO Software 20.04.2016 16:21

если проверка прошла успешно, отключите кнопку. если нет, то не надо.

function validate(form) {
  // perform validation here
  if (isValid) {
    form.mySubmitButton.disabled = true;
    return true;
  } else {
    return false;
  }
}

<form onsubmit = "return validate(this);">...</form>

Это более простой, но похожий метод, чем то, что предлагает rp:

function submit(button) {
        Page_ClientValidate(); 
        if (Page_IsValid)
        {
            button.disabled = true;
        }
}

 <asp:Button runat = "server" ID = "btnSubmit" OnClick = "btnSubmit_OnClick" OnClientClick = "submit(this)" Text = "Submit Me" />

Установите для кнопки видимость «нет»;


btnSubmit.Attributes("onClick") = document.getElementById('btnName').style.display = 'none';

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

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

MGOwen 10.11.2009 04:00

... и разве вам не нужно, чтобы он не исчезал, если проверка на стороне клиента не удалась?

MGOwen 10.11.2009 04:05

Я не большой поклонник написания всего этого javascript в коде программной части. Вот как выглядит мое окончательное решение.

Кнопка:

<asp:Button ID = "btnSubmit" runat = "server" Text = "Submit" OnClick = "btnSubmit_Click" OnClientClick = "doSubmit(this)" />

Javascript:

<script type = "text/javascript"><!--
function doSubmit(btnSubmit) {
    if (typeof(Page_ClientValidate) == 'function' && Page_ClientValidate() == false) { 
        return false;
    }    
    btnSubmit.disabled = 'disabled';
    btnSubmit.value = 'Processing. This may take several minutes...';
    <%= ClientScript.GetPostBackEventReference(btnSubmit, string.Empty) %>;    
}
//-->
</script>

Только что слышал о свойстве DisableOnSubmit элемента <asp: Button>, например:

<asp:Button ID = "submit" runat = "server" Text = "Save"
    OnClick = "yourClickEvent" DisableOnSubmit = "true" />

При рендеринге атрибут кнопки onclick выглядит так:

onclick = "this.disabled=true; setTimeout('enableBack()', 3000);
  WebForm_DoPostBackWithOptions(new
  WebForm_PostBackOptions('yourControlsName', '', true, '', '', false, true))

А функция javascript "enableBack ()" выглядит так:

function enableBack()
{
    document.getElementById('yourControlsName').disabled=false;
}

Таким образом, когда кнопка нажата, она отключается на 3 секунды. Если форма отправляется успешно, вы никогда не увидите кнопку повторного включения. Если, однако, какие-либо валидаторы выйдут из строя, кнопка снова станет активной через 3 секунды.

Все это просто путем установки атрибута на кнопку - код javascript не нужно писать вручную.

Это было бы здорово, но в моей версии ASP.NET этого нет. Какую версию ты используешь!?

MGOwen 10.11.2009 03:50

В то время я использовал последнюю версию: Visual Studio 2008. Я больше не работаю на этого работодателя, поэтому я не могу проверить что-либо еще (пакеты обновлений, версию среды выполнения .NET и т. д.). Приносим извинения за задержку с ответом!

Steve J 29.01.2010 20:49

Теперь, когда я думаю об этом, я считаю, что на странице использовался AJAX, так что это могло быть расширением, предоставленным набором инструментов.

Steve J 29.01.2010 20:58

Обратите внимание, что подход rp приведет к двойной отправке вашей формы, если вы используете кнопки с UseSubmitBehavior = "false".

Я использую следующий вариант кода rp:

public static void DisableButtonOnClick(Button button, string clientFunction)
{
    // If the page has ASP.NET validators on it, this code ensures the
    // page validates before continuing.
    string script = "if (typeof(Page_ClientValidate) == 'function') { "
            + "if (!Page_ClientValidate()) { return false; } } ";

    // disable the button
    script += "this.disabled = true; ";

    // If a secondary JavaScript function has been provided, and if it can be found, call it.
    // Note the name of the JavaScript function to call should be passed without parens.
    if (!string.IsNullOrEmpty(clientFunction))
        script += string.Format("if (typeof({0}) == 'function') {{ {0}() }} ", clientFunction);

    // only need to post back if button is using submit behaviour
    if (button.UseSubmitBehavior)
        script += button.Page.GetPostBackEventReference(button) + "; ";

    button.Attributes.Add("onclick", script);
}

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

Конечно, вы должны ТАКЖЕ написать для этого код на стороне сервера, поскольку вы не можете полагаться на проверку, даже если она выполняется из-за отсутствия или конкретной реализации JavaScript. Однако, если вы полагаетесь на сервер, контролирующий состояние включения / выключения кнопки, то в любом случае у вас практически нет способа заблокировать пользователя, отправляющего форму несколько раз. По этой причине у вас должна быть какая-то логика для обнаружения нескольких отправок от одного и того же пользователя за короткий период времени (например, одинаковые значения из одного сеанса).

одно из моих решений следующее:

добавьте скрипт в page_load вашего aspx файла

    HtmlGenericControl includeMyJava = new HtmlGenericControl("script");
    includeMyJava.Attributes.Add("type", "text/javascript");
    includeMyJava.InnerHtml = "\nfunction dsbButton(button) {";
    includeMyJava.InnerHtml += "\nPage_ClientValidate();";
    includeMyJava.InnerHtml += "\nif (Page_IsValid)";
    includeMyJava.InnerHtml += "\n{";
    includeMyJava.InnerHtml += "\nbutton.disabled = true;";
    includeMyJava.InnerHtml += "}";
    includeMyJava.InnerHtml += "\n}";
    this.Page.Header.Controls.Add(includeMyJava);

а затем установите параметры кнопки aspx следующим образом:

<asp:Button ID = "send" runat = "server" UseSubmitBehavior = "false" OnClientClick = "dsbButton(this);" Text = "Send" OnClick = "send_Click" />

Обратите внимание, что onClientClick помогает отключить кнопку, а UseSubmitBehaviour отключает традиционное поведение страницы при отправке и позволяет asp.net отображать поведение отправки в соответствии с пользовательским скриптом.

удачи

-Waqas Aslam

Поэтому простое отключение кнопки с помощью javascript не является кроссбраузерным вариантом. Chrome не отправит форму, если вы просто используете OnClientClick = "this.disabled=true;"
Ниже представлено решение, которое я тестировал в Firefox 9, Internet Explorer 9 и Chrome 16:

<script type = "text/javascript">
var buttonToDisable;
function disableButton(sender)
{
    buttonToDisable=sender;
    setTimeout('if (Page_IsValid==true)buttonToDisable.disabled=true;', 10);
}
</script>

Затем зарегистрируйте disableButton с событием щелчка кнопки отправки формы, один из способов:

<asp:Button runat = "server" ID = "btnSubmit" Text = "Submit" OnClientClick = "disableButton(this);" />

Стоит отметить, что это решает вашу проблему с отключением кнопки в случае сбоя проверки на стороне клиента. Также не требует обработки на стороне сервера.

Основываясь на ответе @rp., я изменил его, чтобы вызвать пользовательскую функцию и либо отправить и отключить в случае успеха, либо "остановиться" в случае ошибки:

public static void DisableButtonOnClick(Button ButtonControl, string ClientFunction)
{
    StringBuilder sb = new StringBuilder(128);

    if (!String.IsNullOrEmpty(ClientFunction))
    {
        sb.AppendFormat("if (typeof({0}) == 'function') {{ if ({0}()) {{ {1}; this.disabled=true; return true; }} else {{ return false; }} }};", ClientFunction, ButtonControl.Page.ClientScript.GetPostBackEventReference(ButtonControl, null));
    }
    else
    {
        sb.Append("return true;");
    }

    ButtonControl.Attributes.Add("onclick", sb.ToString());
}

Обнаружил код rp в нашем устаревшем приложении, которое боролось с каким-то сумасшедшим поведением.

Отследил это до странной комбинации срабатывания события - когда DisableButtonOnClick () использовался для кнопки asp внутри UpdatePanel, POST будет отправлен дважды (один раз doPostBack, добавленным DisableButtonOnClick (), и один раз UpdatePanel). Однако это произошло только с некоторыми браузерами (ранние версии Edge, но не последние, и IE11 сделал это, Chrome и FireFox нет (по крайней мере, версии, с которыми я тестировал)). Я предполагаю, что Chrome и более новые версии Edge каким-то образом внутренне справляются с этим сценарием. Отслеживание проблемы с помощью F12 devtools в IE - два POST происходят так близко друг к другу, что первый сразу же АБОРТИРУЕТСЯ, но при некоторых условиях (задержка в сети, загрузка пользовательского компьютера и т. д.) Запрос действительно доходит до сервера до того, как браузер сможет прервать. Таким образом, это приводит к кажущимся случайным двойным сообщениям, возникающим из-за нажатия кнопок по всей системе, и отследить это было сложно. Исправление состоит в том, чтобы добавить «return false»; после doPostBack, чтобы предотвратить включение UpdatePanel, когда используются старые браузеры.

TL; DR - остерегайтесь этого кода на кнопках в панелях обновлений. Это хороший подход и хороший метод, но в моем (вероятном крайнем) случае есть потенциальная проблема.

ps - Я бы прокомментировал сообщение rp, но у меня нет репутации. Подумал, что это может быть полезно для будущих путешественников.

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