Welcome Guest Search | Active Topics | Sign In | Register

Update Progressbar Options
Vagyok C4
Posted: Monday, July 30, 2007 9:25:09 AM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
Can you give an example of how I would update the progressbar from the server side during a LONG running process?

Code: C#
ProgressBar1.Maximum = ProcessQueue.Count;
ProgressBar1.Value = 0;

foreach (Process in ProcessQueue)
{
     if (Process.DoSomething())
          UpdateProgressBarHere();
}

private void UpdateProgressBarHere()
{
     // Here's where i need some help!
     ProgressBar1.Value++;
}
eo_support
Posted: Monday, July 30, 2007 9:32:20 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

ProgressBar is designed to be updated on the client side, not on the server side:

http://www.essentialobjects.com/ViewDoc.aspx?t=JSDoc.Public.ProgressBar.setValue.html

If you do need the ProgressBar to be updated on the server side, you can use a Callback control to call server side code to return the current progress value, then call the above function to set the value.

Thanks
Vagyok C4
Posted: Monday, July 30, 2007 10:14:43 AM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
Can you give a quick code example of how this would work. I know nothing about javascript, and less about callbacks.

eo_support
Posted: Monday, July 30, 2007 10:47:12 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

It would be rather hard to explain to you if you are not familar with Javascript. :) So I'll try to break it into a couple of steps.

The first step is to know how to update the progress bar. We have two samples demonstrating how to do that at here:

http://www.essentialobjects.com/Demo/Default.aspx?path=ProgressBar

Once you are familar with that, you want to play with the Callback control a bit. You can start by looking at the samples in the demo projects, but then you will need to play with this function:

http://www.essentialobjects.com/ViewDoc.aspx?t=JSDoc.Public.Global.eo_Callback.html

Once you learned how this function work, you would need to proceed to these two things:

1. Use window.setTimeout or whatever other mechanism to call eo_Callback;
2. Handle this event to update progress bar;

http://www.essentialobjects.com/ViewDoc.aspx?t=EO.Web.Callback.ClientSideAfterExecute.html

So the whole flow is like timer (window.setTimeout) -> eo_Callback -> ClientSideAfterExecute -> ProgressBar.setValue. This will be running repeatly until the task is done.

We maybe able to add a demo into the demo project when we release our next update.

Thanks
Vagyok C4
Posted: Monday, July 30, 2007 1:21:45 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
I think I understand what we're are doing, but I'm not doing something right. Can you give a quick working example? I have the progressbar on a control that I need to update say every 5 seconds. I have a callback on the control as well.

Server Side:

Code: C#
public void SendNOW(NewsLetterEntity N)
    {
        Page.RegisterStartupScript("PBShow", "javascript: setTimeout('executeCallback()',5000)");
        ProgressBar1.Maximum = SubscriberCollection.ActiveSubscribers.Count;
        ProgressBar1.Value=0;
        foreach (SubscriberEntity S in SubscriberCollection.ActiveSubscribers)
        {
            WebMail.SendNewsletter(N, S);
            ProgressBar1.Value++;
        }
    }

    protected void Callback1_Execute(object sender, EO.Web.CallbackEventArgs e)
    {
        e.Data = ProgressBar1.Value.ToString();
    }



On the client side: I have the following code

Code: JavaScript
function executeCallback() {
        eo_Callback('callback1');
}

function updateProgressBar(var Callback, var Output, var Value) {
    eo_GetObject('ProgressBar1').setValue(Value);
}


I'm not sure how to set the Timer code as I am in a control, and not sure how to access the Body onload event.

Any help would be greatly appreciated.

eo_support
Posted: Monday, July 30, 2007 1:44:16 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

You don't need to do Page.RegisterStartupScript. The easiest way is to do:

Code: HTML/ASPX
<body onload="setTimeout('executeCallback()',5000)">


Also, setTimeout only triggers once, so in order for it to trigger repeatly, you would want to do:

Code: JavaScript
function executeCallback() 
{
    eo_Callback('callback1');
    setTimeout('executeCallback()',5000);
}


The rest of your code looks good.

Thanks
Vagyok C4
Posted: Monday, July 30, 2007 1:48:01 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
The problem I have now is accessing the <body onload> from the code in the component. This control doesn't have the <body> tag as it is in the MasterPage.

How can I either 1) update the body tag on the masterpage from a control? or 2) start the process from my control.

Thanks
eo_support
Posted: Monday, July 30, 2007 2:02:40 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

In that case you will need to use RegisterStartupScript. The only catch with this function is you need to enclose your code in the script tag. For example this is wrong:

Page.RegisterStartupScript("window.alert('hi!')");

This is correct:

Page.RegisterStartupScript("<script language='javascript'>window.alert('hi!')</script>");


Thanks
Vagyok C4
Posted: Monday, July 30, 2007 3:21:59 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
You know I'm still having a problem :( I move this code out of a control and put it directly on the page. I still cannot get this thing working. Plus, the ProgressBar control seems to have a display bug in it. I'll try to attach some screen captures.

First, Here's my code:

Code: HTML/ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="88836f54-1540-4760-a9c1-a9b7e105edad.aspx.cs"
    Inherits="_88836f54_1540_4760_a9c1_a9b7e105edad" %>
<%@ Register Assembly="EO.Web" Namespace="EO.Web" TagPrefix="eo" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>

    <script type="text/javascript">
        function executeCallback() {
            window.alert(eo_GetObject('ProgressBar1').getValue());
            eo_Callback('Callback1');
            setTimeout('executeCallback()',5000);
        }

        function updateProgressBar(var Callback, var Output, var PBValue) {
            eo_GetObject('ProgressBar1').setValue(PBValue);
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
        <div style="text-align: center">
        <eo:Callback ID="Callback1" runat="server" OnExecute="Callback1_Execute" ClientSideAfterExecute="updateProgressBar">
        </eo:Callback>
            <table style="width: 100%">
                <tr>
                    <td align="center" class="TextHeader">
                        Sending Newsletters</td>
                </tr>
                <tr>
                    <td align="center">
                        <eo:ProgressBar ID="ProgressBar1" runat="server" BorderColor="Black" BorderStyle="Solid"
                            BorderWidth="1px" ControlSkinID="None" Height="16px" IndicatorColor="0, 192, 0"
                            Value="30" Width="500px">
                        </eo:ProgressBar>
                    </td>
                </tr>
                <tr>
                    <td align="center">
                        <VAM:Button ID="ButtonGO" runat="server" OnClick="ButtonGO_Click" OnClientClick="eo_Callback('Callback1')"
                            Text="GO" Width="100px" /></td>
                </tr>
            </table>
        </div>
    </form>
</body>
</html>



Code: C#
public partial class _88836f54_1540_4760_a9c1_a9b7e105edad : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void ButtonGO_Click(object sender, EventArgs e)
    {
        int X = 100;
        ProgressBar1.Maximum = X;
        ProgressBar1.Value = 0;
        for (int i = 0; i < X; i++)
        {
            ProgressBar1.Value++;
            System.Threading.Thread.Sleep(500);
        }
    }

    protected void Callback1_Execute(object sender, EO.Web.CallbackEventArgs e)
    {
        e.Data = ProgressBar1.Value.ToString();
    }
}


Here are my screen captures:

eo_support
Posted: Monday, July 30, 2007 3:30:06 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

Somehow the screenshot is not working. However I spotted at least one error in your code: you can not perform task like what you did in ButtonGO_Click. ASP.NET threading modal prevent you from having two requests from the same user to be executed at the same (ever wondering why you never need to worry about threading issues in an ASP.NET application?). So in your case when your ButtonGO_Click is being executed, the subsequent Callback requests will all be queued up by ASP.NET until ButtonGO_Click is done.

You will have to modify your code to make ButtonGO_Click to initiate the task and return immediately. Only after that ASP.NET will pick up subsequent Callback requests.

Thanks
Vagyok C4
Posted: Wednesday, August 1, 2007 4:55:10 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
Ok, so there's no way to push a javascript update to the client WHILE this long process is running?

U know I ran across some ProgressBar code that did allow to issue an update via javascript while a long process was running, and the client would update it's value. Once the process was all done, in the source code you could see every update that was sent. (I only wish I could find it)

Also, I've updated my screen capture of the progress bar. It displays this was in the IDE as well.

Your thoughts?
eo_support
Posted: Wednesday, August 1, 2007 4:59:22 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

Try to remove align="center" on the enclosing td. Center alignment doesn't work on quite somethings and unfortunately progress bar is one of them.

Thanks
eo_support
Posted: Wednesday, August 1, 2007 5:11:15 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Hi,

As for the long running process, I believe what you concluded is false. The problem is your code is blocking current request. The client side javascript is unable to get any status information not because the client side code is unable to query the server, but because your server code is never able to respond until your long running task is done. It has nothing to do with the progress bar or whatever client solution you might use.

Try think your server code as "one man", it can not perform the long running task and also response status inquiry at the same time unless you explicitly make it multi-threaded. As such I do believe the only solution is to change your server side code structure.

Thanks

Vagyok C4 wrote:
Ok, so there's no way to push a javascript update to the client WHILE this long process is running?

U know I ran across some ProgressBar code that did allow to issue an update via javascript while a long process was running, and the client would update it's value. Once the process was all done, in the source code you could see every update that was sent. (I only wish I could find it)

Also, I've updated my screen capture of the progress bar. It displays this was in the IDE as well.

Your thoughts?
Vagyok C4
Posted: Wednesday, August 1, 2007 8:29:07 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
I understand the threading issues with regards to the client PULLing data from the server while it's busy.

What I'm talking about is the server PUSHing the update to the client while this long running process is going.
eo_support
Posted: Wednesday, August 1, 2007 8:40:59 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
I see what you meant. However a web server never pushes. One of the biggest reason why HTTP is so popular is because of its request-response model.
Vagyok C4
Posted: Wednesday, August 1, 2007 8:43:41 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
We can do a Response.Write("<script>SetVallue(10);</script>"); Resposne.Flush(); which would "push" the updated value over to the client.
eo_support
Posted: Wednesday, August 1, 2007 8:58:57 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
No. That will not work. Response.Write only works when there is a request that it is responding to. HTTP works on a request-response basis and whatever you do with Response is only responding a request initiated by the client.
Vagyok C4
Posted: Wednesday, August 1, 2007 9:27:45 PM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
Ah ha! I found my old Progress Bar Code...

The BLOG Document describing this functionality can be found at this link:
Progress Bar Blog Entry

Your thoughts?
eo_support
Posted: Thursday, August 2, 2007 6:31:21 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,096
Thanks for sharing, the idea is rather clever. However it has to use a separate page with only the progressbar, I guess if you can live with that then you can go with it.
Vagyok C4
Posted: Thursday, August 2, 2007 8:39:19 AM
Rank: Member
Groups: Member

Joined: 7/28/2007
Posts: 21
Is it possible to have your control make it easy to implement something like this? Giving the ability to progress bar out a long running process this way is a feature I think a lot of people would be interested in.


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.