skip to Main Content

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


  1. When you click the button the page goes to postback where your server side function (sub) runs and creates a script on the page.

    <script type="text/javascript">
       //<![CDATA[
       alert('You Clicked Me!'); //return false;//]]>
    </script>
    

    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.

    <asp:Button Text="Run" ID="btnRun" runat="server" 
       OnClientClick="alert('You Clicked Me on client!'); return false;" />
    

    and remove your server side code.

    Login or Signup to reply.
  2. 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:

            <asp:Button ID="myButton" runat="server" CssClass="btn"
                Text="Click Me!"                
                OnClientClick="jobStarted();">
            </asp:Button>
    
            <div id="myprogress" style="display:none">
                <img src="../Content/wait2.gif" width="32"
                    style="float:left;width:32px;"
                    />
                <h3>Processing, please wait....</h3>
            </div>
    
            <script>
    
                function jobStarted() {
    
                    $('#myprogress').show()
    
                }
    
            </script>
    

    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:

        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
    
        <div style="padding:35px">
    
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
    
                    <asp:Button ID="myButton" runat="server" CssClass="btn"
                        Text="Click Me!"
                        OnClientClick="jobStarted();"></asp:Button>
    
                    <div id="myprogress" style="display: none">
                        <img src="../Content/wait2.gif" width="32"
                            style="float: left; width: 32px;" />
                        <h3>Processing, please wait....</h3>
                    </div>
    
                    <script>
                        function jobStarted() {
    
                            $('#myprogress').show()
                        }
                    </script>
    
                </ContentTemplate>
            </asp:UpdatePanel>
    
        </div>
    

    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:

            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
    
                    <asp:Button ID="myButton" runat="server" CssClass="btn"
                        Text="Click Me!"
                        OnClientClick="$('#myprogress').show()"></asp:Button>
    
                    <div id="myprogress" style="display: none">
                        <img src="../Content/wait2.gif" width="32"
                            style="float: left; width: 32px;" />
                        <h3>Processing, please wait....</h3>
                    </div>
    
                </ContentTemplate>
            </asp:UpdatePanel>
    

    So, now we eliminated 2 JavaScript routines.

    The result and effect are thus:

    enter image description here

    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:

    <asp:Button ID="myButton" runat="server" CssClass="btn"
        ClientIDMode="Static"
        Text="Click Me!"
        OnClientClick="$('#myButton').hide();$('#myprogress').show()"></asp:Button>
    

    And now the result is this:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search