Console-ish output in a browser, how?

G

gnewsgroup

In my web application, I would like to dynamically display the
progress of a process, something like:

Collecting user input ...
Saving user profile ...
Generating report in PDF ...
Dispatching report to user email ...

This is something like the installation progress display of DotNetNuke
or the Oracle's web-based enterprise manager.

Any idea about how this is implemented? I sorta think it is a iframe,
but just a wild guess.

Thanks.
 
B

bruce barker

its done with server push. turn off page bufferring

DoSomeWork();
Response.Write("working 1...<br>");
Rsponse.Flush();
DoSomeWork();
Response.Write("working 2...<br>");
Rsponse.Flush();

the markup must be simple or the browser will not render it until all of it
is recieved.

-- bruce (sqlwork.com)
 
D

David R. Longnecker

My recommendation would be to use a ListBox control and insert items into
it as you return out messages to the user.

Using .Insert() at the zero index ensures that the newest messages show up
at the top...

Here's an example:

On your ASPX page:

<div>
<asp:ListBox ID="ConsoleOutput" runat="server" />
</div>

In your code-behind, classes, etc:

// Put an "item" for each line in the "console" output.
ConsoleOutput.Items.Insert(0, "Collecting user input ...");
ConsoleOutput.Items.Insert(0, "Saving user profile ...");
ConsoleOutput.Items.Insert(0, "Generating report in PDF ...");
ConsoleOutput.Items.Insert(0, "Dispatching report to user email
....");

ConsoleOutput.Items.Insert(0, "Collecting user input again... ");
ConsoleOutput.Items.Insert(0, "Saving another user profile ...");
ConsoleOutput.Items.Insert(0, "Generating another report in PDF
....");
ConsoleOutput.Items.Insert(0, "Dispatching the final report to
user email ...");

Events could fire off the control updating and/or placing it in an UpdatePanel
so your users can see it "scroll"...

HTH!

-dl
 
G

gnewsgroup

its done with server push. turn off page bufferring

DoSomeWork();
Response.Write("working 1...<br>");
Rsponse.Flush();
DoSomeWork();
Response.Write("working 2...<br>");
Rsponse.Flush();

I had thought that it must be something trickier than this. Will
Thread.Sleep(2000) work in a webpage? In other words, will the next
output appear after 2 seconds' elapse like so?

DoSomeWork();

Thread.Sleep(2000);

Response.Write("working 1...<br>");
Rsponse.Flush();
DoSomeWork();

Thread.Sleep(2000);

Response.Write("working 2...<br>");
Rsponse.Flush();

I tried Thread.Sleep before in a webpage, it does not seem to work.
 
G

gnewsgroup

My recommendation would be to use a ListBox control and insert items into
it as you return out messages to the user.

Using .Insert() at the zero index ensures that the newest messages show up
at the top...

Here's an example:

On your ASPX page:

<div>
<asp:ListBox ID="ConsoleOutput" runat="server" />
</div>

In your code-behind, classes, etc:

// Put an "item" for each line in the "console" output.
ConsoleOutput.Items.Insert(0, "Collecting user input ...");
ConsoleOutput.Items.Insert(0, "Saving user profile ...");
ConsoleOutput.Items.Insert(0, "Generating report in PDF ...");
ConsoleOutput.Items.Insert(0, "Dispatching report to user email
...");

ConsoleOutput.Items.Insert(0, "Collecting user input again... ");
ConsoleOutput.Items.Insert(0, "Saving another user profile ...");
ConsoleOutput.Items.Insert(0, "Generating another report in PDF
...");
ConsoleOutput.Items.Insert(0, "Dispatching the final report to
user email ...");

Events could fire off the control updating and/or placing it in an UpdatePanel
so your users can see it "scroll"...

HTH!

-dl

Thanks, I think your idea is absolutely cool. But, I guess it is then
necessary to CSS-format your listbox and make the frame and scroll bar
invisible. What do you think?
 
D

David R. Longnecker

That's a good question--I've never had a great deal of luck styling ListBox
controls. If I need really heavy duty theming, I tend to create composite
controls of my own.

If you wanted the box to expand dynamically (rather than scroll), that's
possible too.. You could refactoring out the .Insert command and do something
like:

protected void Page_Load(object sender, EventArgs e)
{
// Put an "item" for each line in the "console" output.
ConsoleWriter(ConsoleOutput, "Collecting user input ...");
ConsoleWriter(ConsoleOutput, "Saving user profile ...");
ConsoleWriter(ConsoleOutput, "Generating report in PDF ...");
ConsoleWriter(ConsoleOutput, "Dispatching report to user email
....");

ConsoleWriter(ConsoleOutput, "Collecting user input again... ");
ConsoleWriter(ConsoleOutput, "Saving another user profile ...");
ConsoleWriter(ConsoleOutput, "Generating another report in PDF
....");
ConsoleWriter(ConsoleOutput, "Dispatching the final report to
user email ...");
}

protected void ConsoleWriter(ListBox listBox, string textToWrite)
{
listBox.Items.Insert(0, textToWrite);
listBox.Rows = listBox.Items.Count + 1;

}

That'll keep the ListBox 1 line "bigger" (that may not even be necessary,
can try with and without the +1) than the data it's holding. I'm sure others
on here have some creative ideas as well--I've just never sat down and hacked
out the actual ListBox control. :)

Good luck!

-dl
 
M

Mohamad Elarabi

You can also set Response.Buffer = False at the top of your page and you
won't have to do all the Response.Flush() commands. Essentially you're
turning off bufferring so all responses are immediately sent to the browser.

tip: This also helps when a part of the page is taking a long time to load
while the rest of the page is fast. Instead of holding everybody hostage
you'd turn off the buffer and the slow image etc would load on its own sweet
time.
 
Z

zhaojk

That's a good question--I've never had a great deal of luck styling ListBox
controls. If I need really heavy duty theming, I tend to create composite
controls of my own.

If you wanted the box to expand dynamically (rather than scroll), that's
possible too.. You could refactoring out the .Insert command and do something
like:

protected void Page_Load(object sender, EventArgs e)
{
// Put an "item" for each line in the "console" output.
ConsoleWriter(ConsoleOutput, "Collecting user input ...");
ConsoleWriter(ConsoleOutput, "Saving user profile ...");
ConsoleWriter(ConsoleOutput, "Generating report in PDF ...");
ConsoleWriter(ConsoleOutput, "Dispatching report to user email
...");

ConsoleWriter(ConsoleOutput, "Collecting user input again... ");
ConsoleWriter(ConsoleOutput, "Saving another user profile ...");
ConsoleWriter(ConsoleOutput, "Generating another report in PDF
...");
ConsoleWriter(ConsoleOutput, "Dispatching the final report to
user email ...");
}

protected void ConsoleWriter(ListBox listBox, string textToWrite)
{
listBox.Items.Insert(0, textToWrite);
listBox.Rows = listBox.Items.Count + 1;

}

That'll keep the ListBox 1 line "bigger" (that may not even be necessary,
can try with and without the +1) than the data it's holding. I'm sure others
on here have some creative ideas as well--I've just never sat down and hacked
out the actual ListBox control. :)

Good luck!

-dl

Thank you very much. It's nice, but I still would rather not to see
the frame of the listbox. I believe this can be done through css
formating. I've seen people do similar stuffs with TextBox.
 
B

bruce barker

with the minor issuse that it will not appear until all processing is done
(page renders).

while you could use an ajax update panel, you would need to make a
request/postback per step.

a common server push approach is to post to an iframe, then render script to
update the main frame (google does this).

-- bruce (sqlwork.com)
 
G

gnewsgroup

with the minor issuse that it will not appear until all processing is done
(page renders).

while you could use an ajax update panel, you would need to make a
request/postback per step.

a common server push approach is to post to an iframe, then render script to
update the main frame (google does this).

-- bruce (sqlwork.com)

I just tried your approach, like what you've said, it will not appear
until all processing is done. In other words, you don't see those
output one after another with some pause in between them, even if you
use Thread.Sleep(5000) after each output. It does not work. You see
them all at once when the page renders.

Not sure how DotNetNuke does it for their installation process.
 
M

Mohamad Elarabi [MCPD]

You must set Response.Buffer = False for response to go to the client
immediately. Please read my previous post.

Thanks,
 
G

gnewsgroup

You must set Response.Buffer = False for response to go to the client
immediately. Please read my previous post.

Thanks,

Yes, Mohamad, thank you. I did set Response.Buffer= false; But it
does not work as expected.
 
M

Mohamad Elarabi [MCPD]

This code works on my box:

<%@ Page Language="VB" Theme="" AutoEventWireup="false" title="Untitled
Page" %>

<%
Response.Buffer = False

System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
%>

And this is the output:

12/21/2007 3:03:34 PM</br>12/21/2007 3:03:36 PM</br>12/21/2007 3:03:38 PM</br>

And this is how it looks in the browser:

12/21/2007 3:03:34 PM
12/21/2007 3:03:36 PM
12/21/2007 3:03:38 PM

It did write it out 2 seconds at a time.
Are you doing this in one of the page events? Maybe you have to do it inline
to work. Let me know if this works for you.

Thanks,

p.s. I put theme="" in the header because I have themes set in the web
config and I wanted to avoid that, you can take it out if you want.
 
G

gnewsgroup

This code works on my box:

<%@ Page Language="VB" Theme="" AutoEventWireup="false" title="Untitled
Page" %>

<%
Response.Buffer = False

System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
%>

And this is the output:

12/21/2007 3:03:34 PM</br>12/21/2007 3:03:36 PM</br>12/21/2007 3:03:38 PM</br>

And this is how it looks in the browser:

12/21/2007 3:03:34 PM
12/21/2007 3:03:36 PM
12/21/2007 3:03:38 PM

It did write it out 2 seconds at a time.
Are you doing this in one of the page events? Maybe you have to do it inline
to work. Let me know if this works for you.

Thanks,

p.s. I put theme="" in the header because I have themes set in the web
config and I wanted to avoid that, you can take it out if you want.

Aha, I tried your code. It indeed works. And as you said, I was indeed
trying to do it in code-behind in Page_Load.

It won't work if I try to update the Text of a Label control in the
code-behind.
 
G

gnewsgroup

This code works on my box:
<%@ Page Language="VB" Theme="" AutoEventWireup="false" title="Untitled
Page" %>
<%
Response.Buffer = False
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
%>
And this is the output:
12/21/2007 3:03:34 PM</br>12/21/2007 3:03:36 PM</br>12/21/2007 3:03:38 PM</br>
And this is how it looks in the browser:
12/21/2007 3:03:34 PM
12/21/2007 3:03:36 PM
12/21/2007 3:03:38 PM
It did write it out 2 seconds at a time.
Are you doing this in one of the page events? Maybe you have to do it inline
to work. Let me know if this works for you.

p.s. I put theme="" in the header because I have themes set in the web
config and I wanted to avoid that, you can take it out if you want.
gnewsgroup said:
On Dec 21, 2:57 pm, Mohamad Elarabi [MCPD]
You must set Response.Buffer = False for response to go to the client
immediately. Please read my previous post.
Thanks,
--
Mohamad Elarabi
MCP, MCTS, MCPD.
Yes, Mohamad, thank you. I did set Response.Buffer= false; But it
does not work as expected.

Aha, I tried your code. It indeed works. And as you said, I was indeed
trying to do it in code-behind in Page_Load.

It won't work if I try to update the Text of a Label control in the
code-behind.

Actually, it won't work even if I try to update the Text of a Label
control in the same aspx file (not in code-behind).
 
M

Mohamad Elarabi [MCPD]

Yes, definitely. That is because Server controls (ones with runat=server) are
not rendered as the page loads part by part. They are rendered in their
entirety and then sent to the browser. Also the whole rendering process
happens after the page_load event.

The response object is sort of like an open channel or pipe to the client
and anywhere within the page's lifetime you can response.write things but
controls are different.

This code can be in the page_Load event and it should work, I've tested it,
but it might get erased or make your page look weird depending on what you're
doing after this.

Let me know if you still need help or this is good for you.

--
Mohamad Elarabi
MCP, MCTS, MCPD.


gnewsgroup said:
This code works on my box:
<%@ Page Language="VB" Theme="" AutoEventWireup="false" title="Untitled
Page" %>
<%
Response.Buffer = False
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
%>
And this is the output:
12/21/2007 3:03:34 PM</br>12/21/2007 3:03:36 PM</br>12/21/2007 3:03:38 PM</br>
And this is how it looks in the browser:
12/21/2007 3:03:34 PM
12/21/2007 3:03:36 PM
12/21/2007 3:03:38 PM
It did write it out 2 seconds at a time.
Are you doing this in one of the page events? Maybe you have to do it inline
to work. Let me know if this works for you.

p.s. I put theme="" in the header because I have themes set in the web
config and I wanted to avoid that, you can take it out if you want.
:
On Dec 21, 2:57 pm, Mohamad Elarabi [MCPD]
You must set Response.Buffer = False for response to go to the client
immediately. Please read my previous post.
Yes, Mohamad, thank you. I did set Response.Buffer= false; But it
does not work as expected.

Aha, I tried your code. It indeed works. And as you said, I was indeed
trying to do it in code-behind in Page_Load.

It won't work if I try to update the Text of a Label control in the
code-behind.

Actually, it won't work even if I try to update the Text of a Label
control in the same aspx file (not in code-behind).
 
M

Mohamad Elarabi [MCPD]

As for making this look presentable among the rest of your page you can have
it load into an iFrame that has no borders. Your main page (default.aspx for
argument sake) will look like a normal presentable page while in it there
will be an iFrame that defaults to about:blank and has no borders, it is
undetectable. In the clientside OnLoad event of the default.aspx page you
will change the src of the iFrame to your consolish page and voila. You can
also go to town and make the onload event of the consolish page change the
display to none on the iFrame itself using the window.parent object, this way
when the process is done the consolish stuff dissappear.

--
Mohamad Elarabi
MCP, MCTS, MCPD.


gnewsgroup said:
This code works on my box:
<%@ Page Language="VB" Theme="" AutoEventWireup="false" title="Untitled
Page" %>
<%
Response.Buffer = False
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
System.Threading.Thread.Sleep(2000)
Response.Write(Now & "</br>")
%>
And this is the output:
12/21/2007 3:03:34 PM</br>12/21/2007 3:03:36 PM</br>12/21/2007 3:03:38 PM</br>
And this is how it looks in the browser:
12/21/2007 3:03:34 PM
12/21/2007 3:03:36 PM
12/21/2007 3:03:38 PM
It did write it out 2 seconds at a time.
Are you doing this in one of the page events? Maybe you have to do it inline
to work. Let me know if this works for you.

p.s. I put theme="" in the header because I have themes set in the web
config and I wanted to avoid that, you can take it out if you want.
:
On Dec 21, 2:57 pm, Mohamad Elarabi [MCPD]
You must set Response.Buffer = False for response to go to the client
immediately. Please read my previous post.
Yes, Mohamad, thank you. I did set Response.Buffer= false; But it
does not work as expected.

Aha, I tried your code. It indeed works. And as you said, I was indeed
trying to do it in code-behind in Page_Load.

It won't work if I try to update the Text of a Label control in the
code-behind.

Actually, it won't work even if I try to update the Text of a Label
control in the same aspx file (not in code-behind).
 
G

gnewsgroup

Yes, definitely. That is because Server controls (ones with runat=server) are
not rendered as the page loads part by part. They are rendered in their
entirety and then sent to the browser. Also the whole rendering process
happens after the page_load event.

The response object is sort of like an open channel or pipe to the client
and anywhere within the page's lifetime you can response.write things but
controls are different.

This code can be in the page_Load event and it should work, I've tested it,
but it might get erased or make your page look weird depending on what you're
doing after this.

Let me know if you still need help or this is good for you.

OK, great. The event-firing order helps me understand why Label
controls don't work like what I want.

I do want to display such progress info in a well-formatted page. I
think that I can output formating HTML markups through
Response.Write(...). A little awkward, but maybe a solution.

Also, I think this effect can be achieved through javascript. I tried
a code snippet found from the web, which tries to update an HTML label
through something like

document.getElementById('the_id_of_the_html_label').innerHtml =
"Saving blah blah...";
setTimeOut(.....);
document.getElementById('the_id_of_the_html_label').innerHtml =
"Something else do display ...";

But, it did not work. I am new to javascript, and I am not sure how
to do this on the client-side.

Thank you once again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top