?
Solved

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

Posted on 2009-04-29
10
Medium Priority
?
1,833 Views
Last Modified: 2012-05-06
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
Comment
Question by:pjhunter2174
  • 6
  • 4
10 Comments
 
LVL 4

Expert Comment

by:cauos
ID: 24265274
could you add your code to check what is the wrong with your code
0
 

Author Comment

by:pjhunter2174
ID: 24265889
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
 
LVL 4

Expert Comment

by:cauos
ID: 24267833
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:pjhunter2174
ID: 24271724
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
 

Author Comment

by:pjhunter2174
ID: 24274155
One clarification..  the javascript error mentioned in my previous comment DOES NOT occur when running on a normal website outside the development environemnt.
0
 
LVL 4

Expert Comment

by:cauos
ID: 24285425
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
 

Author Comment

by:pjhunter2174
ID: 24286497
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
 
LVL 4

Assisted Solution

by:cauos
cauos earned 800 total points
ID: 24287334
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
 

Author Comment

by:pjhunter2174
ID: 24321966
I have been swamped with other projects.  Hopefully I'll get back to this soon.  Stay tuned.
0
 

Accepted Solution

by:
pjhunter2174 earned 0 total points
ID: 24557945
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

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer…
This article discusses how to implement server side field validation and display customized error messages to the client.
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Suggested Courses

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question