Fix: Disabling a button doesn’t fire click event on server side

Problem: You have buttons that get disabled in the Javascript onClick event handler to prevent the user from clicking multiple times. However, the server side OnClick event handler doesn’t get fired.

In this example, Button1 is using validation while Button2 is not (CausesValidation="false").

Before performing action on the button, I check if the client validation is valid as described here.

<script type="text/javascript">

	function disableButton(btn, requiresValidation) {
		if (!requiresValidation || Page_ClientValidate()) { //check validation
			btn.disabled = true;
	};

</script>

<asp:TextBox ID="TextBox1" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="*"
	ControlToValidate="TextBox1" />

<p />
<asp:Button ID="Button1" runat="server" Text="Button with validation"
	OnClientClick="disableButton(this, true)" onclick="Button1_Click" />

<asp:Button ID="Button2" runat="server" Text="Button without validation"
	OnClientClick="disableButton(this)" onclick="Button2_Click" CausesValidation="false" />

This is a common behavior when disabling the button doesn’t allow ASP.NET to know what was called, the button OnClick event doesn’t fire on post-back. How to fix it? You have to let the server know what is making the post back. There are different solutions for this. I will show you a few and you can use whatever suits you. Sometimes, one solution will work, sometimes it won’t but another will. Try them in sequence.

Solutions:

1. Call functions in Javascript to do the post back.

Manually hard coding “__doPostBack” is not a good approach. ASP.NET provides a better method instead, do as following:

protected void Page_Load(object sender, EventArgs e)
{
	PostBackOptions pboButton1 = new PostBackOptions(Button1)
	{
		PerformValidation = true
	};

	PostBackOptions pboButton2 = new PostBackOptions(Button2)
	{
		PerformValidation = false
	};

	Button1.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(pboButton1));

	Button2.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(pboButton2));

			
}

protected void Button1_Click(object sender, EventArgs e)
{
	System.Threading.Thread.Sleep(2000);

	Response.Write("Button with validation was clicked");
}

protected void Button2_Click(object sender, EventArgs e)
{
	System.Threading.Thread.Sleep(2000);

	Response.Write("Button without validation was clicked");
}

2. Use a hidden button

This is trick you can use in case the solution #1 doesn’t work for you. Add an extra button and hide it via CSS (Display:none), then simulate the click event in Javascript.

Notice that I’m using ClientIDMode=”Static” for these buttons so I can use their native Id.

<script type="text/javascript">

	function disableButton(btn, requiresValidation, buttonId) {
		if (!requiresValidation || Page_ClientValidate()) {
			btn.disabled = true;
			document.getElementById(buttonId).click()
		}		
	};

</script>

<asp:TextBox ID="TextBox1" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="*"
	ControlToValidate="TextBox1" />

<p />
<asp:Button ID="Button1" runat="server" Text="Button with validation"
	OnClientClick="disableButton(this, true, 'Button1_fake')" />
<asp:Button ID="Button1_fake" runat="server"  style="display:none;" onclick="Button1_Click"
	ClientIDMode="Static" />

<asp:Button ID="Button2_fake" runat="server"  style="display:none;" onclick="Button2_Click"
	ClientIDMode="Static" CausesValidation="false" />
<asp:Button ID="Button2" runat="server" Text="Button without validation"
	OnClientClick="disableButton(this, false, 'Button2_fake')"  CausesValidation="false" />

Advertisements

One thought on “Fix: Disabling a button doesn’t fire click event on server side

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s