Getting Confirmation From The User

Download the controls, help files, and source code for this article: ConfirmedButtonsDownload.zip

A very common question on the asp.net lists at aspfriends.com is how to make a button which pops up a confirmation message before posting back to the server. I've seen many answers to this, most of them having to do with adding javascript to the onclick handler of the control. But it seems silly to implement the same script over and over again.

Because of this, I decided to create a ConfirmedButton control. After some reflection, I decided that I should also add confirmation to LinkButtons and ImageButtons. Adding confirmation to those three controls covers most instances where confirmation might be needed. This article will only discuss the ConfirmedButton control, but all three controls are available in the download, and the usage applies equally to all three controls. At the top of this article is the download package needed to use the controls and follow along.

How to install them

If you are just interested in using the controls, it will only take a few steps to get them working.

  1. Copy the dll's to your bin folder.
  2. If you have access to the root of the webserver, copy the MetaBuilders_WebControls_client folder and all its contents to the root of the web server. You can skip ahead to the 3rd step. If you do not have access to the root of the webserver, then you'll have to make some changes to your web.config. Open the "MetaBuilders WebControls ConfirmedButton Documentation.chm" help file, and drill down to the ScriptPathRoot property. In the example section, you'll find the changes required to web.config neccessary to tell the controls that the script library is in your application root instead of the server root. After making those changes, copy the MetaBuilders_WebControls_client folder to your application root.
  3. Copy ConfirmedButtonsExample.aspx to your application root.

You now have everything you need to use the confirmed buttons.

A Demo of the ConfirmedButton control

Have you clicked yet?

The code to create that button looks like this:

protected void DemoButton_Click( Object sender, EventArgs e ) {
    Result.Text = "Yes, you have.";
}
<mbcb:ConfirmedButton runat="server" id="DemoButton" onclick="DemoButton_Click" Text="Click me!" Message="Are you sure you want to click this button?" />
<asp:Label runat="server" id="Result">Have you clicked yet?</asp:Label>

It behaves exactly like a normal System.Web.UI.WebControls.Button control, except for one thing. The text in the Message property is displayed to the user in a yes/no dialog box when they click on the button. If you do not set the Message, it defaults to "Are you sure you want to do this?". It's really that simple to use.

Browser Compatibility

The control has full functionality in ie4+, netscape6+, and opera. It should support any other browser which supports document.getElementById or document.all, accessing arbitrary element attributes, and the onclick event the relevant elements. Notice that netscape4 is not included in that list. Under netscape4, the control behaves exactly like a normal Button control.

How it works

On the server-side, the control is rather simple. The Message is stored in ViewState. AddAttributesToRender is overridden to put the Message into the control's tag. OnPreRender is overridden to inject the client-side code into the page. One thing to note about emitting the clientside script is that I use Page.RegisterClientScriptBlock and Page.RegisterStartupScript to make sure that multiple controls, even of different types, can be put on the page and only one reference to the script library will be on the page.

The control gets fairly interesting in the protected ScriptPathRoot property. It checks the web.config for the path setting, and uses a default if it doesn't exist. Those who want to author controls which respond to web.config would do well to understand this section. First, I get a handle on the section using GetConfig with an xpath-like string.

NameValueCollection thisSettings = (NameValueCollection)ConfigurationSettings.GetConfig("metaBuilders.webControls/confirmationScript");

If the section is null, that means the site developer has not chosen to change things, and it returns the normal setting. Otherwise, the developer used a different folder, so return that.

if ( thisSettings != null ) {
    return thisSettings["scriptPathRoot"];
} else {
    return "/MetaBuilders_WebControls_client/Confirmation/";
}

On the client-side is where all the interesting code is. The problem I had to solve was making the confirmation code compatible with the validation framework. In order to do that, I had to make sure I wasn't just blindly overriding the onclick event of the button, and I also wanted to be sure my click handler fired first. To do that, I modeled my hookup code similarly to the validation framework code.

The ConfirmationOnLoad function runs through each registered button id, finds the control on the page, and hooks up the onclick event. ConfirmationHookupControl uses a technique featured in the asp.net validation script which gets the current code of the click event and adds the new code to the beginning.

What's left to do

One common senario that's not addressed with these controls is the very common DataGrid's EditCommandColumn. Unless you do some fancy coding, those will still be just normal buttons. Stay tuned for a future article where I will incorporate this confirmation behavior into there as well.