禁用表单提交按钮
我有一个按钮,在表单提交时我想禁用它,以防止用户多次提交。
我尝试用javascript onclick天真的禁用按钮,但是如果未能通过按钮的客户端验证仍然禁用。
当表单成功提交时(不仅是用户单击时),如何禁用按钮?
这是一个ASP.NET表单,因此,如果可能的话,我希望很好地与asp.net ajax页面生命周期挂钩。
解决方案
在提交处理程序的最后禁用按钮。如果验证失败,则在此之前应返回false。
但是,JavaScript方法不是可以依靠的方法,因此我们还应该具有一些在服务器上检测重复项的方法。
不知道这是否有帮助,但是表单中有onsubmit事件。只要表单提交(通过任何按钮或者控件),就可以使用此事件。
供参考:http://www.htmlcodetutorial.com/forms/_FORM_onSubmit.html
以下功能非常有用,不需要禁用部分,而该禁用部分往往不可靠。只需使用" return check_submit();"作为提交按钮的onclick处理程序的一部分。
还应该有一个隐藏字段,用于保存form_submitted的初始值0;默认值为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; }
一种解决方案是在单击按钮时设置一个隐藏字段,编号为1.
在按钮单击处理程序上,第一件事是检查该数字(如果不是1),则从函数中返回。
我们也许还可以利用表单上可用的onsubmit()javascript事件。实际提交表单时将触发此事件,并且直到完成验证后才应捕获该事件。
旋转一下:
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() ); } }
如果验证成功,则禁用该按钮。如果不是,那就不要。
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';
它不仅可以防止重复提交,而且可以向用户明确指示我们不想多次按下按钮。
我不是在背后的代码中编写所有这些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>
刚刚听说了<asp:Button>的" DisableOnSubmit"属性,如下所示:
<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))
而" enableBack()" JavaScript函数如下所示:
function enableBack() { document.getElementById('yourControlsName').disabled=false; }
因此,单击该按钮后,它将禁用3秒钟。如果表单成功发布,则我们将永远看不到该按钮重新启用。但是,如果任何验证器失败,则3秒钟后按钮将再次启用。
只需在按钮上设置属性即可完成所有操作-无需手动编写任何javascript代码。
请注意,如果我们使用带有UseSubmitBehavior =" false"
的按钮,则rp的方法将双倍提交表单。
我使用以下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或者特定的实现,我们甚至不能依赖于进行验证。但是,如果我们依靠服务器来控制按钮的启用/禁用状态,那么我们基本上就无法阻止用户多次提交表单。因此,我们应该具有某种逻辑,可以在短时间内检测到同一用户的多个提交(例如,同一会话中的相同值)。
我的解决方案之一如下:
将脚本添加到aspx文件的page_load中
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