Introduction
Prevent double-click from most (not all) users when server performs a long process, and distribute as
a Custom Web Server Control.
Background
Since the introduction of
Custom Web Server Controls,
developing a control on top of existing controls is faster than the times of .NET 1.1.
Using the Code
Prior to the birth of Custom Web Server controls, a few developers at CodeProject came out
with the idea of how to do it the hard way. Now it's easy compared with old days. (Portions of my code
were extracted from them as well; credits go to their hard work.)
To start with development, right-click the solution and add an "ASP.NET Server Control" project.
Rename your class, and make your custom control inherit from the existing ASP Button
as below:
public class ClickOnceBtn : System.Web.UI.WebControls.Button
Give a meaningful name here; this will be the name that is displayed in the toolbox:
Override OnPreRender()
as below. What it does is:
- tag the
onClick
event as part of the attribute of our custom Web Server control - register the embedded js function that will be shown later
protected override void OnPreRender(EventArgs e)
{
this.UseSubmitBehavior = false;
this.Attributes.Add("onclick", "javascript:clickOnce(this)");
String csName = "ButtonClickScript";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsClientScriptBlockRegistered(cstype, csName))
{
string[] names = this.GetType().Assembly.GetManifestResourceNames();
if (names.Length > 0)
{
Assembly assembly = this.GetType().Assembly;
const string JAVASCRIPT_RESOURCE = ".disable.js";
Stream st = Assembly.GetExecutingAssembly().GetManifestResourceStream(
assembly.GetName().Name + JAVASCRIPT_RESOURCE);
StreamReader sr = new StreamReader(st);
this.Page.ClientScript.RegisterClientScriptBlock(
this.GetType(), csName, sr.ReadToEnd(), true);
}
}
base.OnPreRender(e);
}
which in-turn calls this JavaScript:
function clickOnce(btn, msg) {
if (typeof (Page_ClientValidate) == 'function') {
if (Page_ClientValidate() == false) { return false; }
}
if (btn.getAttribute('type') == 'button') {
if (!msg || (msg = 'undefined')) { msg = 'Loading...'; }
btn.value = msg;
btn.disabled = true;
}
return true;
}
Remember to set the .js file as an embedded resource. We do not want the host file carried to many individual files, just one DLL.
Yes, that's it. Easy, huh?
Now we create a test harness web-page and add our Custom Web Server Control to the host file.
In case you want to do some client-side verification on the host page, before calling the Custom Web Server Control, the script will be something similar to this:
where confirmProceed()
is:
function confirmProceed() {
var r = confirm("Confirm to proceed?");
if (r == false) {
return false;
}
return true;
}
Points of Interest
If your ASP page contains some validators, it might affect page validation; try to play around with this function:
if (typeof (Page_ClientValidate) == 'function') {
if (Page_ClientValidate() == false) { return false; }
}
History
Coming soon, if any.