Search code examples
javascriptasp.netvb.net

Changing text of label on asp form with vb.net


I'm new to ASP (and javascript) and am trying to update the text of a label on an ASP form from back-end button code (using vb.net, which I am more familiar with).

I want the text to say 'Processing...' when the button is pressed, and then when the rest of the code has finished, I want it to say 'Finished'

I started with a simple:

lblMessage.Text = "Processing..."

This works fine, but the label text doesn't update until the rest of the button code has executed - I want it to update immediately so the user knows to wait for the rest of the code to finish.

I can update the label before the button code runs from the client side by using:

<asp:Button ID="btnUpdate" runat="server" Text="Update Label" OnClientClick="updateLabel(); return false;" />

<script type="text/javascript">
            function updateLabel() {
                // Update the label text immediately on the client side
                var label = document.getElementById('<%= lblMessage.ClientID %>');
                if (label) {
                    label.innerHTML = 'Processing...';
                }
                return false; // Prevent the button from triggering a postback
            }
        </script>

This updates the text immediately from pressing the button, but is inflexible because I cannot vary the text displayed - for example, I might want to have a check on the server side before running the rest of the code that input is valid. If it isn't, I might want the text to say 'Sorry, fill in field x first' or something.

So this is my position:

  1. Using the scipt to update label text, I can't pass it any variables from the back end code to specify the text I want to appear.
  2. Using back-end code to update the label text means it won't execute until the rest of the button code finishes.

Is there a way I can update the text immediately AND be able to change the text used?

Thanks for reading.


Solution

  • Well, if the web page is not posted back to the server, then your code behind can't make changes to the copy of the browser sitting on the client side.

    And of course, if you post back the page then the user can't see changes made to the browser until the server-side code is 100% finished, and the whole copy of the browser is sent back to the client side.

    So, there are a few choices:

    Simple, is to have a button click, but it is VERY short code to START the longer processing loop.

    So, when you start this, then your message on server-side code is for the NEXT step in the process.

    So, in most cases the solutions involve a different mind set. In desktop land, for example if we have some delete command, we can place a confirm message box inside of that delete button code.

    In web land, the solution to confirm dialogs is to flip or reverse the code. Thus, you toss up a dialog prompt (client side), and if the user hits "ok" or "confirm" then the server side delete button code runs.

    Say we have multiple steps, each taking some time, so we want to display a message as to the status of the processing (Step 1.... please wait, then Step 2....please wait etc.).

    So, you can do this:

            <asp:Button ID="cmdStart" runat="server" Text="Start the Process"
                OnClick="cmdStart_Click"  
                CssClass="btn"
                />
            <asp:Button ID="cmdMyProcess" runat="server" Text="Button"
                OnClick="cmdMyProcess_Click"
                ClientIDMode="Static" style="display:none"
                
                />
            <asp:HiddenField ID="CurrentStep" runat="server" Value="0"
                ClientIDMode="Static" />
            <asp:HiddenField ID="NumSteps" runat="server" Value="0"
                ClientIDMode="Static" />
    
            <div id="processarea" style="display:none">
                <img src="../Content/wait2.gif"  width="32" />
                <asp:Label ID="StepMessage" runat="server" Text=""></asp:Label>
            </div>
    
            <script>
    
                $(window).on('load', function() {
    
                    var Steps = $('#NumSteps').val()
                    var StepOn = $('#CurrentStep').val()
                    if (StepOn < Steps) {
                        $('#processarea').show()
                        $('#cmdMyProcess').click()
                    }
                    else {
                        $('#processarea').hide()
                    }
                })
            </script>
    

    So, in most cases, you want/need "some" client side.

    So, now code behind is this:

    Protected Sub cmdStart_Click(sender As Object, e As EventArgs)
    
        NumSteps.Value = 4
        CurrentStep.Value = 0
        StepMessage.Text = "Step 1 - get dog leash"
    
    End Sub
    
    Protected Sub cmdMyProcess_Click(sender As Object, e As EventArgs)
    
        CurrentStep.Value += 1
        Select Case CurrentStep.Value
            Case 1
                ' processing code to get dog leash
                System.Threading.Thread.Sleep(2000)
                StepMessage.Text = "Step 2 - Call dog"  ' setup next step message
            Case 2
                System.Threading.Thread.Sleep(2000)
    
                StepMessage.Text = "Step 3 - Open door to outside"
            Case 3
                System.Threading.Thread.Sleep(2000)
                StepMessage.Text = "Step 4 - take dog for walk outside"
            Case 4
                System.Threading.Thread.Sleep(2000)
                StepMessage.Text = "done"    ' we hide the message, does not show
    
        End Select
    
    End Sub
    

    And the result is this:

    enter image description here

    Now, of course we probably should place the above inside of an update panel, so we don't suffer WHOLE page post backs here.

    However, if we use an update panel, then the jQuery page "on load" does not trigger, since that is quite much the whole idea of an update panel. (to avoid a full-page post back).

    So, assuming we want an update panel. And hey, let's toss in a progress bar for added fun.

    So, in place of on load, we need an event that triggers AFTER the update panel post-back occurs. A little hard to find this event but this works:

    So, now we have this (and I tossed in a progress bar)

           <asp:UpdatePanel ID="UpdatePanel1" runat="server">
               <ContentTemplate>
    
                   <asp:Button ID="cmdStart" runat="server" Text="Start the Process"
                       OnClick="cmdStart_Click"
                       CssClass="btn" />
                   <asp:Button ID="cmdMyProcess" runat="server" Text="Button"
                       OnClick="cmdMyProcess_Click"
                       ClientIDMode="Static" Style="display: none" />
                   <asp:HiddenField ID="CurrentStep" runat="server" Value="0"
                       ClientIDMode="Static" />
                   <asp:HiddenField ID="NumSteps" runat="server" Value="0"
                       ClientIDMode="Static" />
    
                   <div id="processarea" style="display: none">
                       <img src="../Content/wait2.gif" width="32" />
                       <asp:Label ID="StepMessage" runat="server" Text=""></asp:Label>
                       <br />
                       <div id="progressbar" 
                           style="width:400px;background-color:skyblue;">
                       </div>
                   </div>
               </ContentTemplate>
           </asp:UpdatePanel>
    
    
           <script>
               var prm = Sys.WebForms.PageRequestManager.getInstance();
               prm.add_endRequest(myrunone);
               function myrunone() {
    
                   var Steps = Number($('#NumSteps').val())
                   var StepOn = Number($('#CurrentStep').val())
    
                   // pBar(value: StepOn)
                   if (StepOn < Steps) {
                       $('#processarea').show()
                       $('#progressbar').progressbar({ value: StepOn + 1, max: Steps})
                       $('#cmdMyProcess').click()
                   }
                   else {
                       $('#processarea').hide()
                   }
               }
           </script>
    

    And the result is:

    enter image description here

    And last but not least?

    You can adopt push notifications to the browser. So, say your building a chat room, and as each person types, you want to see the results in real time.

    So, you can setup and adopt what is called a web socket. Since there is quite a bit of moving parts, there are a number of tools you can adopt for this purpose. In .net land, that framework is called SignalR, and you can start here:

    https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr

    SignalR is a great concept, but it quite a complex library to adopt, but if you really need some messages "pushed" out to the browser, or real time updates without a post-back, then SignalR is about the best way to go.

    While the above example is mostly server-side code? In most cases, I would adopt some JavaScript and web method calls. So, trying to cobble together some progress bar, or messages with only server-side code? Hum, it not all that great. You can kind of chop away, but after all is done? You wished you just started writing JavaScript for this, and in near all cases, the results of writing JavaScript code and calling some vb.net code behind with a web method call not only works better, but is less “hackly” for the given results.