How to express progress of longer run of JS?

M

Martin Mrazek

Hi,
I check data validity in html form by JS. Something like

for (i=0; i<document.form[0].elements.length; i++) {
chechkValidity(i);
}

Unfortunately, the form[0] has about two thousands elements (it is
statistical questioning form for companies) and execution of this one
cycle takes about twenty seconds.

The problem is, that during these 20 seconds the browser "freezes":
The button activating the cycle disappears and the mouse pointer
doesn't change into "watch" (sandglass) showing that something is
being carried out.

Although after the 20s everything is ok, it is not the nicest behavior
of the form. I don't assume somebody is so impatient to restart during
those 20 seconds. I just want to minimize the users' swearing on my
address and tha's why my question:

??? How to show the progress of that cursed for-cycle?

Thanks
Martin
 
K

KsAdmin

Hi,
I check data validity in html form by JS. Something like

for (i=0; i<document.form[0].elements.length; i++) {
chechkValidity(i);
}

Unfortunately, the form[0] has about two thousands elements (it is
statistical questioning form for companies) and execution of this one
cycle takes about twenty seconds.

The problem is, that during these 20 seconds the browser "freezes":
The button activating the cycle disappears and the mouse pointer
doesn't change into "watch" (sandglass) showing that something is
being carried out.

Although after the 20s everything is ok, it is not the nicest behavior
of the form. I don't assume somebody is so impatient to restart during
those 20 seconds. I just want to minimize the users' swearing on my
address and tha's why my question:

??? How to show the progress of that cursed for-cycle?

Thanks
Martin

Could you possibly have it display a message informing the user to
please wait and the process can take up to 30 seconds.....
Josh Austin
System Administrator
Agent Services of America
ksadmin NOSPAM @comcast.net
www.agentsvs.com (coming soon)
 
I

Ivo

I check data validity in html form by JS. Something like

for (i=0; i<document.form[0].elements.length; i++) {
chechkValidity(i);
}

Unfortunately, the form[0] has about two thousands elements (it is
statistical questioning form for companies) and execution of this one
cycle takes about twenty seconds.

Submit the unvalidated form to the server. Validate it there.
Two reasons:
1. You need to do this anyway for the js-less and code manipulators.
2. It may well be much faster, including the traffic.
The problem is, that during these 20 seconds the browser "freezes":
The button activating the cycle disappears and the mouse pointer
doesn't change into "watch" (sandglass) showing that something is
being carried out.

To do this would require setting a timeout, as any visual effect of scripts
(setting the wait cursor) is only displayed after the script has finished
running. So the form submission would have to be canceled initially etc etc.
I think you 're in for a mess if you go this way.
Ivo
 
R

Richard Cornford

Martin Mrazek wrote:
Unfortunately, the form[0] has about two thousands elements (it is
statistical questioning form for companies) and execution of this one
cycle takes about twenty seconds.
??? How to show the progress of that cursed for-cycle?

To get the browser to re-draw it's display you have to give it a bit of
time to itself, which means stopping javascript execution and then
restarting it with a timeout of some sort. You cannot sensibly do that
in the onsubmit handler of a form without absolutely cancelling the
submission, leaving the only option to programmatically submit the form
when the validation is finished.

Of course inserting regular timeouts into the validation will make it
even slower.

It would probably be more sensible to look into the efficiency of your
code as even for 2000 elements 20 seconds seems very slow.

Richard.
 
I

Ivo

for (i=0; i<document.form[0].elements.length; i++) {
chechkValidity(i);
if ( i%100==0 ) {
window.status( "Processing: " + i );

If you had either tried out your own script, or read the other posts in this
thread, you 'd have known why this will not give you your updating
statusbar, and refrained from elaborating.
Ivo
 
G

Grant Wagner

Martin said:
Hi,
I check data validity in html form by JS. Something like

for (i=0; i<document.form[0].elements.length; i++) {
chechkValidity(i);
}

Unfortunately, the form[0] has about two thousands elements (it is
statistical questioning form for companies) and execution of this one
cycle takes about twenty seconds.

The problem is, that during these 20 seconds the browser "freezes":
The button activating the cycle disappears and the mouse pointer
doesn't change into "watch" (sandglass) showing that something is
being carried out.

Although after the 20s everything is ok, it is not the nicest behavior
of the form. I don't assume somebody is so impatient to restart during
those 20 seconds. I just want to minimize the users' swearing on my
address and tha's why my question:

??? How to show the progress of that cursed for-cycle?

Thanks
Martin

I don't know what you're doing that's taking 20 seconds to iterate over
2000 form elements, but the first thing I'd do is try to resolve that.
First, you can improve performance by caching fully-qualified DOM
references so the loop doesn't have to parse the DOM everytime it
executes:

var formElements = document.forms[0].elements;
for (i=0; i<formElements.length; i++) {
checkValidity(formElements);
}

The reason to pass the reference to the current element to checkValidity()
is so that checkValidity() doesn't have to look up the reference to the
element all over again. So instead of:

function checkValidity(i) {
var element = document.forms[0].elements;
// ... handle "element"
}

it is:

function checkValidity(element) {
// ... handle "element" - notice not additional lookup on the element

Now that that is out of the way, let's assume that the application is
Intranet based, or at least you have control over the environment (no
popup blockers, a limited range of browsers in use, etc). If that's the
case, you could do something like:

progress.html:
---

<body onload="if (opener && opener.startProcessing)
opener.startProcessing();">
<!-- transparent.gif is a 1 x 1 transparent GIF image -->
<span style="background-color:Green;"><img name="progress"
src="/Graphics/transparent.gif" width="1" height="20" /></span>
</body>

progressText.html:
---

<form>
<script type="text/javascript">
for (var i = 0; i < 2000; i++) {
// this is just for testing, obviously this would be your real form
document.writeln('<input type="hidden" />');
}
</script>
<input type="button" value="Go" onclick="go();" />
</form>

<script type="text/javascript">
function go() {
// triggered by the user's action to process the form
// opens a new window with the progress meter, you may
// want to try to position it
window.progressMeter = window.open('progress.html', 'progressMeter',
'height=100,width=300');
}
function startProcessing() {
// triggered by the completed loading of
// the progress meter window
var formElements = document.forms[0].elements;
for (i = 0; i < formElements.length; i++) {
if (i % 10 == 0) {
// update the image once for every 10 elements
// using a setTimeout() helps prevent locking the
// browser entirely and makes this whole thing
// a little bit friendlier to the user
var t = setTimeout('showProgress();', 100);
}
// checkValidity(formElements);
}
}
function showProgress() {
// triggered once for every 10 form elements processed
if (window.progressMeter &&
window.progressMeter.document &&
window.progressMeter.document.images &&
window.progressMeter.document.images['progress']) {

window.progressMeter.document.images['progress'].width += 1;
}
}
</script>

This seemed to work pretty well in IE and Opera 7, making a smooth
expanding image. In Firefox, the green line jumped from 1 pixel wide to
200 pixels wide. Either it iterated through the form MUCH faster (which it
probably did), or Gecko-based browsers don't update the UI when there is
processing intensive JS running (which I've seen before).

Don't forget, adding all this fluff will make the actual form processing
much slower as well. Far better to fix the performance issue in the form
processing instead.

--
| Grant Wagner <[email protected]>

* Client-side Javascript and Netscape 4 DOM Reference available at:
*
http://devedge.netscape.com/library/manuals/2000/javascript/1.3/reference/frames.html

* Internet Explorer DOM Reference available at:
*
http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp

* Netscape 6/7 DOM Reference available at:
* http://www.mozilla.org/docs/dom/domref/
* Tips for upgrading JavaScript for Netscape 7 / Mozilla
* http://www.mozilla.org/docs/web-developer/upgrade_2.html
 
R

Richard Cornford

Andrew Thompson wrote:
(shrugs) Seems to work in both IE6 and
Moz 1.3 on XP. Did I miss something (still)?

We try not to think in terms of "both browsers" these days. But you will
find that Mozilla includes the option of disallowing scripts from
updating/modifying the status bar.

Richard.
 
I

Ian Richardson

Martin said:
Hi,
I check data validity in html form by JS. Something like

for (i=0; i<document.form[0].elements.length; i++) {
chechkValidity(i);
}

I'd suggest:

1. Create an array, e.g. myformstatus[]

1a. Set a new variable to setInterval("isComplete(myform)",20);

2. have a for loop disabling all the form elements, assuming that you
don't want user interaction until the process is complete, just user
feedback. Populate each element of myformstatus[] with a default value,
e.g. null.

3. use your loop with something like myform =
setTimeout(chechkValidity(i),10); so your function is called and the
browser is only hanging for the period of one execution of
chechkValidity() once.

[Note your setTimeout could be
("chechkValidity(i);chechkValidity(i+1);chechkValidity(i+2);",10"); so
that these are executed in blocks rather than just one at a time,
depending on how intensive each call is...]

4. In chechkValidity(), set myformstatus to some other default value,
e.g. "done"

5. Create a function isComplete() which goes through myformstatus[] to
check that all elements have a value of "done". If so, clear the
setInterval() and then have a for loop reenabling all form elements.

Then in your step 3 or 4 you can do whatever feedback to the user you can.

Note this may cause the overall process to take _longer_, but if you do
it in one for loop as you've described you'll hit three problems:

1. It may cause the browser to freeze so long that the browser offers
the option for the user to abandon it, thus potentially causing all
manner of state-related problems. I've found that recent builds of
Mozilla seem to have shortened this time considerably, but there's no
easy way I've found of pre-determining how long this actually is.

2. You won't be able to get feedback to the user, as the browser needs
time to breathe between bursts of Javascript...

3. A browser freeze may be considered by the user as a browser crash!

Just my thoughts - I've not tested this out but it seems to make sense,
at least to me!

Thanks,

Ian
 
J

Jim Ley

Martin said:
3. use your loop with something like myform =
setTimeout(chechkValidity(i),10); so your function is called and the
browser is only hanging for the period of one execution of
chechkValidity() once.


So on win98 this will add a minimum of 106 seconds? (53ms minimum
setTimeout resolution *2000 items, or is my maths out?)

(not that I don't disagree with the need to use setTimeout, but
remember it's a lot of overhead.)

Jim.
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen in
news:comp.lang.javascript said:
So on win98 this will add a minimum of 106 seconds? (53ms minimum
setTimeout resolution *2000 items, or is my maths out?)

More exactly, (2000*) 54.9255 milliseconds. 86400000 / 0x1800B0.

Anyone know of javascript systems where the time quantum is NOT either
55 ms (possibly rounded to 50/60) or 10 ms? RSVP.
 

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
474,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top