Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Forcing a screen update

Status
Not open for further replies.
Dec 8, 2003
17,047
GB
Hi all...

I'm writing some recursive code that parses a tree structure (of some 7000 - 10000 nodes), which takes about 15 - 20 seconds to complete.

I would like some sort of progess indicator to let the user know how the operation is progressing. At present, I have a DIV on the page, and every so often (maybe every 100 - 500 nodes) set the contents of the DIV using:

Code:
document.getElementById('myDivId').innerHTML = 'Node count: ' + myNodeCount;

My problem is that Javascript doesn't appear to be very instant with the screen updating, and doesn't display anything until the entire tree has been parsed (presumably because it is still within a tight loop at 100% CPU utilisation).

While I could use setTimeout to pause momentarily after writing to the screen, over 10000 nodes, these delays every 100 nodes or so would add a considerable amount of time to the total time taken to parse the tree. I would also have to extensively modify my recursion code to be able to stop, and carry on at the same point it left off - something which I'd rather not do if I can avoid it.

So my question: Does anyone know of a way to force the browser to update the screen? Or maybe a better way of creating some sort of progress indicator that works well within a tight loop, but without slowing down the execution of code by too much.

Thanks in advance!
Dan
 
BillyRay said:
which takes about 15 - 20 seconds to complete

If you have a vague idea of how long an operation will take, just use an animated image that runs for about the maximum time you would expect the operation to take (in this case 20 seconds).

It's completely different to any approach you are currently looking at... but I'm guessing that you are trying to do this so the user has *some* kind of ongoing feedback.

Just a thought... doesn't even need to use setTimeOut!

Jeff
 

Unfortunately, the operation will not always take 20 seconds, so offering a fixed-duration animated GIF isn't really an option for a progress meter.

Couple that with the fact that (in IE at least) animated GIFs don't always (in fact, rarely) animate when the browser is in a tight loop and CPU utilisation is at 100%, negates using it even for an animated "Work in progress" display/bar/logo.

One thing to add to the original post - this only has to work in IE, so even using MS-specific hacks is OK by me.

Thanks!
Dan
 

Oh yes - and while I can use the status bar for real-time updates (this seems to work fine), I really want an in-browser display, as some people may have turned off their status bars!

Dan
 
The only on-topic M$-specific hack I know is window.offscreenBuffering... can you check it?
 

Nice idea - I'd not thought of that.

Unfortuntely, it didn't seem to make any difference - the screen update still only happened after the recursion was complete ;o(

Thanks for the suggestion, though!

Dan
 
Dan, is this something you can do server side? I've just recently been toying around with an ASP progress bar using the the graphics from mwolf's tile game. Here's what I have so far:

just swap the database stuff in processor.asp with some database on your local server

main.asp
Code:
<html>
<head>
<title>Data Update Skeleton</title>
<script language=javascript>
</script>
</head>
<body>
<form action='processing.asp' method=post>
<input type=hidden name=from value=main>
<input type=submit value='Submit' name=submitButton>
</form>
</body>
</html>
processing.asp
Code:
<%@ LANGUAGE="JavaScript" %>
<!-- Include file for JScript ADO Constants -->
<!--#include File="adojavas.inc"-->
<%
if (!Request.Form("from").count) {
   Response.Write("Page not accessible");
   Response.End;
}
%>

<html>
<head>
<title>Data Update Skeleton</title>
<script language=javascript>
function processingStatus(bool) {
   document.getElementById("processingDiv").style.visibility = (bool) ? 'visible' : 'hidden';
}
function proBar(inc, msg) {
   document.getElementById("processingDiv").style.left = (document.body.offsetWidth/2)-200;
   document.getElementById("processingDiv").style.top = (document.body.offsetHeight/2)-50;
   document.getElementById("progressBar").style.width = 304;
   document.getElementById("progressBar").style.border = "solid blue 2px";
   document.getElementById("progress").style.width = inc * 3;
   document.getElementById("progress").style.backgroundColor = "blue";
   document.getElementById("progressScore").innerHTML = "&nbsp<b>" + Math.round(inc) + "%</b>";
   document.getElementById("progressMessage").innerHTML = msg;
}
function displayMessage(msg) {
   alert(msg);
}
function finished() {
   document.location = 'main.asp';
}
</script>
</head>
<body bgcolor=#000000>
Processing Data<br>
<input type=hidden name=from value=processing>
<div id=processingDiv style="position:absolute;visibility:hidden;left:0px;top:0px;width:360px;height:65px;background-color:#ffffff">
<table border="0" width="360" height="65" cellspacing="0" cellpadding="2" bgcolor="#ff0000">
<tr>
<td width="100%">
<table border="0" width="100%" height="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="2">
<tr>
<td>
<span id="progressBar" style="text-align: left; width: 304; border: solid blue 2px; font-size : 18pt;">
<span id="progress" style="width: 0; backgroundColor: blue; font-size : 18pt;"></span></span>
<span id="progressScore">&nbsp<b>0%</b>&nbsp&nbsp</span><br>
<span id="progressMessage"></span>
</td></tr></table></td></tr></table>
</div>
<iframe id="processorFrame" src="processor.asp" width=0 height=0></iframe>
</form>
</body>
</html>
processor
Code:
<%@ LANGUAGE="JavaScript" %>
<% Response.Buffer = false; %>
<!-- Include file for JScript ADO Constants -->
<!--#include File="adojavas.inc"-->
<%
oConn.Open(strConn);
oRS.ActiveConnection = oConn;
oRS.CursorType = adOpenStatic;
oRS.LockType = adLockOptimistic;
oRS.CursorLocation = adUseClient;
%>

<script language=javascript>
parent.processingStatus(true);
parent.proBar(0, 'Searching VPOFFICE');
</script>
<%
oRS.Source = "SELECT * FROM VPOFFICE WHERE (OFFICECODE = 'STLX' OR OFFICECODE = 'CRCX')";
oRS.Open();
oRS.Close();
%>
<script language=javascript>
parent.proBar(20, 'Still Searching VPOFFICE.....');
</script>
<%
oRS.Source = "SELECT * FROM VPOFFICE WHERE (OFFICECODE = 'STLX' OR OFFICECODE = 'CRCX')";
oRS.Open();
oRS.Close();
%>
<script language=javascript>
parent.proBar(40, 'STILL Searching VPOFFICE.....');
</script>
<%
oRS.Source = "SELECT * FROM VPOFFICE WHERE (OFFICECODE = 'STLX' OR OFFICECODE = 'CRCX')";
oRS.Open();
oRS.Close();
%>
<script language=javascript>
parent.proBar(60, 'Searching VPVACATION');
</script>
<%
oRS.Source = "SELECT * FROM VPVACATION WHERE FKEY IN (SELECT IDCOL FROM VPAGENTS WHERE OFFICECODE = 'STLX' OR OFFICECODE = 'CRCX')";
oRS.Open();
oRS.Close();
%>
<script language=javascript>
parent.proBar(80, 'STILL Searching VPVACATION.....');
</script>
<%
oRS.Source = "SELECT * FROM VPVACATION WHERE FKEY IN (SELECT IDCOL FROM VPAGENTS WHERE OFFICECODE = 'STLX' OR OFFICECODE = 'CRCX')";
oRS.Open();
oRS.Close();
%>
<script language=javascript>
parent.proBar(100, 'Querys complete!');
parent.displayMessage('done');
parent.processingStatus(false);
parent.finished();
</script>

-kaht

banghead.gif
 

Unfortuntely, this needs to be client-side only, as it will be running locally on PCs.

As the target browser is IE, I could mix VBScript if needed, although I notice that things like DoEvents and WScript.Sleep don't seem to work (the latter doesn't even appear to work in JS although there are many examples that seem to suggest that it should).

I think I might have to re-code my recursion function to allow me to break out and then retun at the same point... But was trying to avoid that.

I'll keep trying, anyway ;o)

Thanks!
Dan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top