Edit: My question got downvoted and then closed because it presumably is a duplicate of this which is not the case. I am not looking for a solution. I want to know why the code that disables the button is not getting executed. I am aware that it has something to do with the "download" functionality that ends the page execution. But, my code to disable the button is before the code for downloading.
Original: I am trying to disable a server side button when the user clicks on it, and, then download a compressed folder, but the button does not get disabled. Does anyone know the reason?
Button:
<asp:Button ID="btnDownload" runat="server" Text="Click here to download" />
Code-behind:
'click event for the button
Private Sub btnDownload_Click(sender As Object, e As EventArgs) Handles
btnDownload.Click
'disable button
btnDownload.Enabled = False '<--- doesn't have any effect
'download folder
Dim docType As String = Request.QueryString("docType")
DownloadZip(docType)
End Sub
'sub-routine to download compressed folder
Private Sub DownloadZip(docType As Integer)
Dim zipPath As String = getPath(docType)
Dim file As FileInfo = New FileInfo(zipPath)
If file.Exists Then
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" & file.Name)
Response.AddHeader("Content-Length", file.Length.ToString())
Response.ContentType = "application/zip"
Response.WriteFile(file.FullName)
Response.Flush()
file.Delete()
Response.[End]()
End If
End Sub
Well, even if you could disable the button, the problem is the user would not see that change in the browser until the file was downloaded anyway.
Keep in mind that the whole page is being sent up to server side, and then code behind runs to modify that COPY of the page up on the server. The client side will not see any changes until such time all code behind is completed, and then a fresh WHOLE NEW copy of the page is then transmitted back from the server.
Only after 100% of the server-side code is complete, then does the WHOLE page make the trip back down to the browser side, and is then fully re-loaded and refreshed client side.
In other words, even if this could work, the user not going to see the disabled button until such time all code is complete, and the browser page travels back from server to client (which of course is too late)
This sample code shows this effect:
Markup:
<asp:Button ID="Button1" runat="server" Text="disable this button test"
CssClass="btn"
OnClick="Button1_Click"
OnClientClick ="mywait();return true;"
/>
<br />
<br />
<br />
<div id="mywaitDiv" style="display:none">
<h3>Waiting for server code to complete</h3>
<h3>so we can see button disable code run</h3>
<img src="Content/wait2.gif" />
</div>
<script>
function mywait() {
// show the div area with the wait message
$('#mywaitDiv').show()
}
</script>
And server side code for the button:
Protected Sub Button1_Click(sender As Object, e As EventArgs)
Me.Button1.Enabled = False
System.Threading.Thread.Sleep(3000) ' fake 3 second long running process
End Sub
So, asp.net buttons have provisions for both a client side click event (runs first), and then the post-back and the button server side code runs. The above assumes you have jQuery installed and setup and working.
The effect of the above code is thus this:
Note how we do NOT see the button disable until all of the server code is complete.
And since when server code is 100% complete, note how we don't have to re-hide the div area, since once again, a WHOLE FRESH page with your code behind is transmitted from the server. So, even in above, we don't see the button disable until such time all of the server side code is complete. You don't thus see changes "as" the server side code runs, but only see all of the changes to the browser DOM when the WHOLE PAGE makes the final trip back from server to client side.
However, we have a second and greater issue:
If you decide to transmit a file from the server, then the web page is NOT transmitted back from the server, but only the file. In other words, you can’t “both” transmit a web page response and transmit a file response in one operation.
Web based software is a message + response system. The server can transmit back a web page, or the server can transmit back a file – but both cannot be done in one operation. As a result, your changes by code behind are never seen, nor is a whole new fresh web page sent back from the server, since your sending a file from the server. So you ONLY are allowed one "message" response back from a client side request to the server. That can be the file, or web page.
For the most part, this means you need to disable (or hide) the button client side, and then allow the post back to run your code behind which in turn transmits a file from the server, and not the web page.
In fact, failure to grasp the page life cycle will give rise to “many” different and unexpected behaviors when moving from desktop-based development to web based. So, clearing the “response” buffer, and then writing code to transmit a file means the web page is never transmitted from the server to client, but your file is sent. As noted, the server response is just that – a “one time” response and that response can be the web page (that your code behind modified), or it can be a file you send – but you still limited to “one” response from the server.
However, it is rather easy to hide a button when clicked, and asp.net buttons have provisions that allows BOTH client-side code, and server-side code to run on a click event.
So, add the above client side code to your button click, it will hide. In fact, we hope you don't have to re-show the button, since that goal becomes VERY difficult to do, since we have no means to know when the file download is complete.
So, in fact your code behind is working, is running, is making changes to the web page, but without the changed web page being sent back to the client side, you never such the effect of that code behind that did run to disable the button.
So, client side code to hide the button could be this:
<asp:Button ID="Button1" runat="server" Text="disable this button test"
CssClass="btn"
OnClick="Button1_Click"
OnClientClick ="myhide(this);return true;"
/>
<script>
function myhide(mybtn) {
$(mybtn).hide()
}
</script>
Disabling is far more difficult, since if you disable the button with client side code, then the button is now disabled, and the server side code will not trigger nor run! (hence, go with above .hide() concept).