.Net ramblings
# Friday, 09 September 2005
An asp.net button that disables itself automatically after clicking.

Some users of a web application i wrote insist on clicking buttons more than once, probably out of impatience. this often causes duplicate key exceptions with the database, because the first time they clicked the button the record was created, and the second time they clicked it, an exception is thrown, so they get the error screen and don't know what they did wrong. 

i wanted to write a button control that would disable itself automatically and re-enable itself once it was finished.  i couldn't find any good samples out there.  javascript is obviously the answer, and the solution i came up with is quite simple.  here's the code: currently only works with .Net 1.1:

	/// <summary>
/// A button control that disables itself when clicked, and changes the text to "Please wait..."
/// This is to prevent duplicate clicks by impatient or novice users.
/// It requires the button to be placed in a server form.
/// </summary>
[DefaultProperty("Text"), ToolboxData("<{0}:SmartButton runat=server></{0}:SmartButton>")]
public class SmartButton : Button
{

/// <summary>
/// Add an 'onClick' attribute to disable the button when it is clicked, and submit the form,
/// invoking the postback.
///
/// The onClick code handles the case where __EVENTTARGET is registered on the page, in which case
/// this variable is set to the button ID, and the form is submitted.
/// The other case is where __EVENTTARGET does not exist on the page, i found this sometimes
/// occurred on pages with only one button. In this case, the form is simply submitted, and the
/// button_click event will be raised by virtue of the default submit button in the form.
/// </summary>
protected override void Render(HtmlTextWriter output)
{
string onClick = "if(this.form != null && this.form.__EVENTTARGET != null){ this.form.__EVENTTARGET.value='" + this.UniqueID + "'; this.disabled = true; this.value = 'Please wait...'; this.form.submit(); } else this.form.submit(); ";
if(this.Attributes["onclick"] != null) // prepend the existing onClick attributes
onClick = this.Attributes["onclick"].ToString() + onClick;
this.Attributes.Add("onclick", onClick);
base.Render(output);
}

protected override void OnClick(EventArgs e)
{
// do the OnClick code first
base.OnClick (e);

// then reset the enabled + text values to their original state
int insertAt = Math.Max(this.Page.Controls.Count-1, 0); // never insert at -1 if there are no controls on the page
this.Page.Controls.AddAt(insertAt, new LiteralControl(String.Format(@"
<script>
if(document.getElementById('{0}') != null)
{{
document.getElementById('{0}').disabled = false;
document.getElementById('{0}').value = '{1}';
}}
</script>
", this.UniqueID, this.Text)));
}
}

Friday, 09 September 2005 15:41:29 (GMT Daylight Time, UTC+01:00)  #    Comments [2]  Asp.Net

Monday, 12 September 2005 08:21:11 (GMT Daylight Time, UTC+01:00)
Hi Tim.

I'm rather novice at ASP .NET. If i'd like to use this kind of "SmartButton" what should I do with this code snippet to make it reusable in different solutions?

Thank you in advance.
Roberto.
Roberto
Monday, 12 September 2005 09:20:26 (GMT Daylight Time, UTC+01:00)
hi Roberto,
you could create a class library project, and add this class to it. when you compile it, you'll have a dll. you can reference this dll to all your projects that want to use the button control. then you should be able to drag and drop the control from the 'my user controls' tab on the toolbox on the left hand side in visual studio. if it isn't listed in the toolbox, right click the toolbox and add/remove items. then browse to your dll, and click ok, it should appear then as 'SmartButton' under 'my user controls'.
let me know how you get on.
thanks
tim
Tim Mackey
OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

[Captcha]Enter the code shown (prevents robots):

Live Comment Preview