Given the following –
<%--Front-End HTML On ASPX Control--%>
<script type="text/javascript">
function jobStarted(){
alert("Job started.rnThis will take a while.");
return false;
}
function jobFinished(){
alert("Job finished!");
return false;
}
</script>
<asp:Button id="myButton" runat="server" Text="Click Me!" OnClientClick="jobStarted();">
</asp:Button>
Back End Page Code:
Private Sub OnClicked(sender as Object, e As EventArgs) Handles myButton.Click
'Long running task code goes here...
ScriptManager.RegisterStartupScript(
Me, [GetType], "ImClicked",
$"jobFinished();", True)
End Sub
When a user clicks the button, the message displays as expected, the task runs to completion, and the ‘completed’ message then displays.
However, if a user refreshes the page after clicking the button, the ‘completed’ message will display again ‘on its own’.
What do I need to do to make it so the ‘completed’ message will display to the user when they click the button, but not again if they refresh the page after clicking the button?
2
Answers
When you click the button the page goes to postback where your server side function (
sub
) runs and creates a script on the page.The script runs after postback and persists during page refresh. If you want to run a script only after button click you can add
OnClientClick
attribute to the button.and remove your server side code.
Ok, there are a few issues here.
Of course, using JavaScript "Alert()" is a big problem, since it halts code, and often will freeze up the UI.
In most cases, then it is better, and in fact simpler to show some "working" message from the client-side code. The beauty of this approach is then you don’t need ANY code to run once the button (server side) code has completed.
So, I suggest this approach:
So, note how we do NOT have to hide the div after the processing is done. This is due to the post-back and round trip model the browser has.
When you click the button, the page is posted back to the server. With that client-side JavaScript then that code runs to display our spinner and text area.
At this point we are waiting for the server to complete the post back and send a WHOLE new fresh copy of the web page back to the client-side browser.
Hence, with that whole new fresh copy of the web page having been sent back to client side, then the spinner div and text will "hide" automatic for you, since that markup been re-created and re-sent from the server.
Thus, we don’t even need hide code anymore!
Of course, the next issue is a 100% VERY different issue, and that is of the user hitting refresh button. Your real issue is not that the JavaScript code runs again, but in fact the submit (post-back) button will be also clicked and run again.
This is standard and correct browser behavior, since if some issue occurred on your page after clicking the button, then a refresh makes the most sense to re-do, and re-load what you intended.
In other words, if the user experiences a bad internet connection, or breakage, then hitting refresh is correct and by design. Thus, such code should be written in such a way that it don’t matter if has to run again.
Of course, one way around this issue is to prevent a full-page post back.
Hence, you could introduce an update panel.
Hence this markup:
In above, I am using jQuery for easy selecting of the div area, and using the .hide() method.
In fact, I can 100% eliminate the need for 2 JavaScript functions, and write the code this way:
So, now we eliminated 2 JavaScript routines.
The result and effect are thus:
So, in effect, I would avoid the JavaScript alert(), since it blocks browser updating, and often prevents refreshing of the web page.
So, the issue of the user hitting refresh? Well, it going to re-trigger any previous button hit that caused a full-page post back, since that is the correct intention and design of using the browser re-fresh button.
In most cases, this strong suggests that a submit button should mean the user has completed their task, and the page in most cases should thus navigate to some other page.
As noted, writing code in which hitting the button again should not matter. Since, if you remain on that page, then the user is free to hit the button again, are they not?
Hence, you should allow the refresh to click the button again, since that means the user may well have had poor wi-fi or some issue. So the better solution here is to write code that allows the code to run again without harm.
So, keep in mind that introduction of a Update Panel means that the user now can’t actually refresh the page if there was some internet connection issue or problem by hitting the refresh button. They would in theory have to hit refresh, and then hit your button inside of the update panel for correct operation and expectations in regards to hitting the browser refresh button.
Of course, it is possible that this question is part of a larger desire to have a conformation dialog for the button, and even being able to trigger such dialogs from the server side. I can expand and show how this can be done, if that was you ultimate goal here.
If the goal is to change the standard browser behavior in which the refresh button will and does re-click the submit button? Then introduction of the update panel solves this issue.
Edit: hide button on click to wait until server side code is completed
So, the follow up issue is to hide the button when click until such time the server side code has completed.
So, the button code can become this:
And now the result is this: