I'm dealing with a large ASP.NET project (Web From, Framework 4.6).
The issue is when user click on a button , button should show as disabled immediately and after a lengthily calculation is done but should show enabled.
I was able to recreate the issue with a very sample code:
aspx code:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication2.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Button Task Example</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Click Me" OnClick="Button1_Click"
OnClientClick="disableButton(this);"/>
<br />
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</div>
</form>
<script type="text/javascript">
function disableButton(button) {
button.disabled = true;
return true;
}
</script>
</body>
</html>
C# Code:
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Button1.Enabled = true;
}
protected void Button1_Click(object sender, EventArgs e)
{
Thread.Sleep(30000);
Button1.Enabled = true;
Button1.Text = "Done!";
}
}
}
So with this code, as soon I click on the button, button gets disabled, but Button1_Click method never run.
If I remove OnClientClick="disableButton(this);"
then Button1_Click runs. Seem OnClientClick="disableButton(this);
somehow blocks server side events.
My guess is this behavior is per design. If client side code disable a button, then server side event handler won't get fired.
Update: OK I was wrong, per documentation if after JavaScript code disables the button, returns true then server side click event should run.
If OnClientClick
is set then the server-side OnClick
only runs if OnClientClick
returns true.
For that to happen you would need to add return
as in OnClientClick="return disableButton(this);"
.
However... it turns out that in order to do the "OnClick", WebForms adds another handler somewhere - possibly onMouseUp - that doesn't run if the button is disabled before it is that handler's turn.
A fix for that is to slightly delay to disableButton
call:
OnClientClick="setTimeout(() => disableButton(this), 0); return true"/>
This will run disableButton
as soon as the browser is done with whatever is in the click handlers themselves.