• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1922
  • Last Modified:

How can I update a progress bar from the codebehind of the page?

I have a client page that iterates through a number of records.  I want to display a progess bar to the user.  I have an AJAX update panel and a timer instantiated on the form with a label control in the update panel.  I have a timer.tick event handler defined in the codebehind.  I thought that when the timer event fired, the tick event handler would update the label with the currrent percent complete statistic and the update panel box would show the result.

Alas, nothing happens.  I must be missing something simple.  All the examples of progress bars I've seen seem much more complicated.  I have to admit however, its not clear to me how the code behind, while executing the for loop, can handle the tick event and do a partial page postback.  What am I missing, and how can I accomplish this?
0
pjhunter2174
Asked:
pjhunter2174
  • 6
  • 4
2 Solutions
 
cauosCommented:
could you add your code to check what is the wrong with your code
0
 
pjhunter2174Author Commented:
This code is part of a page based on a master page structure. I have a button on the page (btnValidate) that starts the long process.  In the isPostback=false block I insert the code:

btnValidate.Attributes.Add("onClick", "javascript:startTimer();")

So, when the user clicks the validate button, the javascript starts the timer and returns true so the postback fires.

In the aspx I insert the script function:
<script type="text/javascript">
    function startTimer(){
        var timer;
        timer=window.document.getElementById("ctl00_ModuleInfoPlaceholder_Timer1")
        timer.enabled=true;
        return true;
    }
</script>

My codebehind then as a sub to handle the Timer1.Tick event. In this event I am simply assigning the number of applications completed (a global variable, set in another method that is doing the processing work) to the label contained in the update panel.

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            lblProgress.Text = nAppsDone.ToString
End Sub

The updatepanel is contained in a table cell and is described in the attached code snippet.
What is happening is the user clicks validate, and nothing happens on the page until the process is complete and the results are displayed.  There is no update of the text label, lblProgress
<!-- This is a table row where the update panel and label are declared -->      
<tr>
  <td>Progress and results:</td>
  <td>
    <asp:UpdatePanel ID="updProgress" runat="server">
    <ContentTemplate>
       <asp:Label ID="lblProgress" runat="server"></asp:Label>
       <asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000"></asp:Timer>
    </ContentTemplate>
    <Triggers>
       <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
    </Triggers>
    </asp:UpdatePanel>
  </td>
</tr>

Open in new window

0
 
cauosCommented:
the cause of this problem is when you click the button it call the startTimer function which in turn enable the timer to start; but actually this made the timer doesn't work;
you can add the button inside the update panel and enable the timer from VB code like this
 
Protected Sub btnValidate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnValidate.Click
        Timer1.Enabled = True
    End Sub

now there is no need to javascript function also there is no post back when you click on the button
<tr>
                    <td>
                        Progress and results:</td>
                    <td>
                        <asp:UpdatePanel ID="updProgress" runat="server">
                            <ContentTemplate>
                                <asp:Label ID="lblProgress" runat="server"></asp:Label>
                                <asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000" OnTick="Timer1_Tick">
                                </asp:Timer>
                                <asp:Button ID="btnValidate" runat="server" Text="Button" />
                            </ContentTemplate>
                            <Triggers>
                                <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
                                <asp:AsyncPostBackTrigger ControlID="btnValidate" EventName="Click" />
                            </Triggers>
                        </asp:UpdatePanel>
                    </td>
                </tr>

Open in new window

0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
pjhunter2174Author Commented:
I tried what you suggested and it still doesn't work.  Now I am getting a javascript error:
Error: Access is denied
URL: http://localhost:1779/StaffPages/MassOperations/ValidateApplications.aspx

Obviously this is in the development environment, but I get the same when I publish to an actual site.  Could this be because the codebehind is busy processing the loop and can't deal with the timer.tick event?

Here is by btnValidate code:
        Protected Sub btnValidate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnValidate.Click
            Timer1.Enabled = True
            Session.Timeout = 180 '3 hours (session.timeout is in minutes)
            btnValidate.Enabled = False
            lblProgress.Text = "Validation started."
            validateapps()
       End Sub

And the timer.tick handler:
        Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
                 lblProgress.Text = "Apps processed=" + nAppsDone.ToString
        End Sub

where nAppsDone is a page global and updated in the validateApps() method.  When I click the Validate button I get 2 of the above javascript errors, then the message "Validation started" appears in the update panel.  After the process is complete, I the validation summary successfully prints in the updatepanel.  But, no progress messages.
              <asp:UpdatePanel ID="updProgress" runat="server">
                  <ContentTemplate>
                    <asp:Button ID="btnValidate" runat="server" CssClass="btnStyle" Text="Validate" /><br />
                     <asp:Label ID="lblProgress" runat="server" CssClass="lblStyle"></asp:Label>
                    <asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="1000">
                    </asp:Timer>
                  </ContentTemplate>
                  <Triggers>
                      <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
                      <asp:AsyncPostBackTrigger ControlID="btnValidate" EventName="Click" />
                  </Triggers>
              </asp:UpdatePanel>

Open in new window

0
 
pjhunter2174Author Commented:
One clarification..  the javascript error mentioned in my previous comment DOES NOT occur when running on a normal website outside the development environemnt.
0
 
cauosCommented:
i think there is a problem in the return value of nAppsDone.ToString; check if there is a problem in you method that calculate the number of applications "validateapps()"
0
 
pjhunter2174Author Commented:
No it's fine because when the process ends I print out nAppsDone and it is the correct number.  Also, I added a global variable nTicks which is incremented every time the Timer1.Tick event fires and it stays at zero.

I still think this is related to the processing loop and the Timer1.Tick event handler being part of the same thread.  Would putting a thread.sleep(500) in the application processing loop help be of any use?  I'll try that, but that would just further slow the processing loop if it were to work.
0
 
cauosCommented:
the variable nTicks  will still zero because it define in every page load; you must define this variable as shared (static variable); and there is no need to make the thread sleep for 500 millisecond; because you can set the interval in the timer itself.

what i guess that every time the timer tick triggered the page load called; so maybe your function initialize something so it will stay zero. use debugging and see what is going on when you call the function(validateapps())
0
 
pjhunter2174Author Commented:
I have been swamped with other projects.  Hopefully I'll get back to this soon.  Stay tuned.
0
 
pjhunter2174Author Commented:
I have a solution, though there may be a more elegant way to achieve the result. I need two timers, one in the update panel and the other in the code behind. I use a system.timers.timer object in the code behind with an interval of 500ms.  When the user clicks the "Validate" button, I enable both this timer and the updatepanel timer (interval=1 sec).  The btnValidate_click handler then finishes normally and both timers start.  The codebehind timer, of course, has nothing to do with the rendered page.  When It fires, I disable it permanently and start the long running ValidateApps process.  The update panel timer then fires on 1 sec intervals and works properly.

Before, I had been trying to fire the ValidateApps process either from the btnValidate_click handler or the first time the update panel timer fired in the timer_tick handler.  The problem with that was once control was passed to the ValidateApps routine, control never came back.  I think I needed the second codebehind timer to allow the postback to complete and then asynchronously start the validateApps process.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now