I have several server pages that take a few seconds to process after clicking the submit button. Some users get impatient and click it multiple times causing the page to process multiple requests. I'm looking for a way to only allow a user to click the button
once.
I thought I had it solved with some javascript. I surrounded the button with a span tag and assigned an onclick event that changed style-visibility to hidden. This worked fine if the page didn't return any validation errors. Well, it worked in Mozilla but
not in IE. In Mozilla the submit button is redisplayed when validation errors are displayed, but in IE the button is still hidden.
If I could find a suitable solution, I'd like to encapsulate it into a custom control so I can reuse it.
I'd prefer not to use a thirdparty library, especially one that has a price tag.
Would it be possible to call a javascript function with the onclick event that would replace the button with a wait message, and then perform postback?
Thanks for your suggestions. This project was pushed aside shortly after it began ... which explains my lack of updates. I think I may have found a solution. I haven't tried this on a form with anything in it yet, I was just playing around at home with
it.
The setTimeout() in disable() is there to simulate a slow postback event, like updating a few hundred rows in a database. So in an application, line 13 would change to:
__doPostBack('"+control.id+"','');
I stuck the hidden LinkButton on line 24 in there so that the page would generate a __doPostBack() function. I'm sure there is a better way to do that ...
1 // ...2 public class WebForm1 : System.Web.UI.Page
3 {
4 protected System.Web.UI.WebControls.LinkButton linkButton;
5 protected Label label;
6 7 private void Page_Load(object sender, System.EventArgs e)
8 {
9 // Put user code to initialize the page here10 if (IsPostBack)
11 {
12 label.Text += "postbacked ";
13 }
14 }
15 // ...
This simply appends text to the label on each post back.
Any suggestions for improvement are welcomed. I'll update when I have made some more progress.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace JRummell.Web
{
public class WebForm1 : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e){}
protected void btnSubmit_ServerClick(object sender, EventArgs e)
{
// fake some processing ...for (int i=int.MinValue; i<int.MaxValue; i++)
;
}
override protected void OnInit(EventArgs e)
{
this.Load += new System.EventHandler(this.Page_Load);
base.OnInit(e);
}
}
}
I ran into that problem before and haven't found a good solution yet. I suppose you could register a client script that enables the button on page load ... or overload the validation event and enable it there ....
john.rummell
Member
40 Points
8 Posts
Button that prevents multiple clicks
Jul 14, 2006 04:28 PM|LINK
I thought I had it solved with some javascript. I surrounded the button with a span tag and assigned an onclick event that changed style-visibility to hidden. This worked fine if the page didn't return any validation errors. Well, it worked in Mozilla but not in IE. In Mozilla the submit button is redisplayed when validation errors are displayed, but in IE the button is still hidden.
If I could find a suitable solution, I'd like to encapsulate it into a custom control so I can reuse it.
Thanks!
alexds
Member
417 Points
85 Posts
Re: Button that prevents multiple clicks
Jul 27, 2006 02:11 PM|LINK
The AspLib Button has this behavior. See it
http://asplib.net
john.rummell
Member
40 Points
8 Posts
Re: Button that prevents multiple clicks
Jul 27, 2006 02:20 PM|LINK
Would it be possible to call a javascript function with the onclick event that would replace the button with a wait message, and then perform postback?
alexds
Member
417 Points
85 Posts
Re: Button that prevents multiple clicks
Jul 27, 2006 02:29 PM|LINK
jammycakes
Participant
1315 Points
274 Posts
Re: Button that prevents multiple clicks
Jul 27, 2006 03:20 PM|LINK
john.rummell
Member
40 Points
8 Posts
Re: Button that prevents multiple clicks
Aug 30, 2006 02:36 AM|LINK
Thanks for your suggestions. This project was pushed aside shortly after it began ... which explains my lack of updates. I think I may have found a solution. I haven't tried this on a form with anything in it yet, I was just playing around at home with it.
1 <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="WebApplication1.WebForm1" %> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 3 <HTML> 4 <HEAD> 5 <title>WebForm1</title> 6 <script type="text/javascript"> 7 function disable(control) 8 { 9 //var control = document.getElementById(controlID); 10 control.disabled = true; 11 control.value = "wait ..."; 12 control.className = "inactive"; 13 setTimeout("__doPostBack('"+control.id+"','')", 5000); 14 } 15 </script> 16 <style type="text/css"> 17 input.active { background-color: lightgrey; color: black; border: 1px solid black; } 18 input.inactive { background-color: red; color: white; border: 1px solid black; } 19 </style> 20 </HEAD> 21 <body> 22 <form id="Form1" method="post" runat="server"> 23 <asp:Label ID="label" Runat="server" /> 24 <asp:LinkButton id="linkButton" style="VISIBILITY: hidden" EnableViewState="False" Runat="server" /> 25 <input type="button" class="active" onclick="disable(this)" id="Button1" value="click me" /> 26 </form> 27 </body> 28 </HTML>The setTimeout() in disable() is there to simulate a slow postback event, like updating a few hundred rows in a database. So in an application, line 13 would change to:
I stuck the hidden LinkButton on line 24 in there so that the page would generate a __doPostBack() function. I'm sure there is a better way to do that ...
This simply appends text to the label on each post back.
Any suggestions for improvement are welcomed. I'll update when I have made some more progress.
"client side postback"
john.rummell
Member
40 Points
8 Posts
Re: Button that prevents multiple clicks
Sep 07, 2006 07:30 PM|LINK
I came up with a better solution based on the above code and made a control out of it. Here it is.
the control:
using System; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Text; namespace JRummell.Web.Controls { /// <summary> /// A button that uses client side code to disable itself and display a wait /// message when the onclick event is raised. Inherits HtmlInputButton. /// </summary> public class PleaseWaitButton : HtmlInputButton { private string activeCssClass; private string inactiveCssClass; private string GetClientScript() { StringBuilder script = new StringBuilder(); script.Append("<script type='text/javascript' language='javascript'> function disableButton(control) { "); script.AppendFormat("control.disabled = true; control.value = 'please wait ...'; control.className = '{0}'; __doPostBack(control.id,''); ", InactiveCssClass); script.Append("} </script>"); return script.ToString(); } public string ActiveCssClass { get { return activeCssClass; } set { activeCssClass = value; } } public string InactiveCssClass { get { return inactiveCssClass; } set { inactiveCssClass = value; } } protected override void OnLoad(EventArgs e) { Page.GetPostBackEventReference(this); if (!Page.IsClientScriptBlockRegistered(ClientID)) Page.RegisterClientScriptBlock(ClientID, GetClientScript()); Attributes.Add("onclick", "disableButton(this);"); Attributes.Add("class", ActiveCssClass); base.OnLoad (e); } } }the aspx page that uses it:
the codebehind:
present
Member
309 Points
65 Posts
Re: Button that prevents multiple clicks
Sep 13, 2006 03:20 PM|LINK
john.rummell
Member
40 Points
8 Posts
Re: Button that prevents multiple clicks
Sep 13, 2006 03:28 PM|LINK
present
Member
309 Points
65 Posts
Re: Button that prevents multiple clicks
Sep 13, 2006 04:00 PM|LINK
Here you go:
/// <summary>
/// Build click once button with page validation
/// </summary>
private void BuildClickOnceButton(WebControl ctl)
{
System.Text.StringBuilder sbValid = new System.Text.StringBuilder();
sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { ");
sbValid.Append("if (Page_ClientValidate() == false) { return false; }} ");
sbValid.Append("this.value = 'Please wait...';");
sbValid.Append("this.disabled = true;");
sbValid.Append(ctl.ClientID + ".disabled = true;");
//GetPostBackEventReference obtains a reference to a client-side script function that causes the server to post back to the page.
sbValid.Append(ClientScript.GetPostBackEventReference(ctl, ""));
sbValid.Append(";");
ctl.Attributes.Add("onclick", sbValid.ToString());
}