Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

ClickOnce Button Server Control Using Custom Web Server Control

4.83/5 (4 votes)
14 Dec 2012CPOL2 min read 16.3K   138  
Prevent double-click from users when server performs long process, and distribute as a Custom Web Server Control.

ClickOnce Button

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.

asp.net server control

Rename your class, and make your custom control inherit from the existing ASP Button as below:

C#
// Your control will inherit from existing ASP Button
public class ClickOnceBtn : System.Web.UI.WebControls.Button

Give a meaningful name here; this will be the name that is displayed in the toolbox:

asp.net server control

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
C#
protected override void OnPreRender(EventArgs e)
{
    this.UseSubmitBehavior = false;
    this.Attributes.Add("onclick", "javascript:clickOnce(this)");

    // Define the name and type of the client script on the page.
    String csName = "ButtonClickScript";
    Type cstype = this.GetType();
    // Get a ClientScriptManager reference from the Page class.
    ClientScriptManager cs = Page.ClientScript;
    // Check to see if the client script is already registered.
    if (!cs.IsClientScriptBlockRegistered(cstype, csName))
    {
        string[] names = this.GetType().Assembly.GetManifestResourceNames();
        if (names.Length > 0)
        {
            // Write out the web resource url.
            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:

JavaScript
function clickOnce(btn, msg) {
    // Test if we are doing a validation
    if (typeof (Page_ClientValidate) == 'function') {
        // if we are doing a validation, return if it's false
        if (Page_ClientValidate() == false) { return false; }
    }
	
    // Ensure that the button is not of type "submit"
    if (btn.getAttribute('type') == 'button') {
        // The msg attibute is absolutely optional
        // msg will be the text of the button while it's disabled
        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.

Embedded Resource

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.

asp.net server control

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:

client-side verification

where confirmProceed() is:

HTML
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:

JavaScript
// Test if we are doing a validation
if (typeof (Page_ClientValidate) == 'function') {
    // if we are doing a validation, return if it's false
    if (Page_ClientValidate() == false) { return false; }
}

History

Coming soon, if any.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)