...

View Full Version : How do I prevent a line from executing before previous event is complete?



codegreen
12-13-2006, 11:23 PM
Hi,
I have a form that upoads an image and then immediately after the javascript updates the div where the image is to appear. Unfortunately, the refresh occurs immediately after and the image does not load.
Ex.

function UploadAndRefresh()
{
...
...
form.submit(); //this uploads the image
RefreshDiv('mydiv');
}

Is there a way to make sure the form.submit() has completed before I execute the RefreshDiv('mydiv') line?

Thanks for your time.

vegu
12-14-2006, 01:47 AM
humm, maybe im miss-reading this, but as soon as you submit a form (assuming were talking about your regular form here, and not some ajax inspired project of your own) it navigates away from the current page sending the request to the path you specified in the form's action tag.

So i am assuming youre working a framed environment where the form is in frame 1 and the div is in frame 2? There isnt really a way to check for javascript when the uploading is done, as the page with the form is navigating away to the server script that handles the upload as soon as you submit the form.

However what you could do is send XmlHttpRequests to the server that the file i s uploaded to and check if the upload is done (when the file is at the target location in its complete state), when it is then update the div.

However im still not sure if i read your problem correctly if i did and you need some code examples let me know, im kinda chilling right now anyways ;)

codegreen
12-14-2006, 01:59 AM
vegu,
Thanks alot.
You are pretty much reading the problem correctly. The form is in an iframe. How would I go about using XMLHttpRequest to prevent the execution of the refresh line until the file has been uploaded?

Would it be something like:

...
form.submit();
Ajax XMLHttpRequest CheckProgress();
RefreshDiv('mydiv');

Won't there be the same general issue with the RefreshDiv('mydiv') executing before the Ajax CheckProgress() functio has completed?

Thanks Again.

vegu
12-14-2006, 02:17 AM
The way i would do it is that the onsubmit event of the form that does the upload triggers a timer (on the other frame) that sends requests to the server , about 1 every 1000 ms should do, since you dont want to bombard the server :D.

Basically you would check the status of each XmlHttpRequest object once it has gotten a response from the server, when the status is 200 (ie the image exists at the location, or in other words the upload is complete) then the image is ready and the div can be updated.

Gimme a couple mins for code examples :D

Edit: actually just had a better less complicated idea for a solution, dont need to ajaxify it ;) just a sec

vegu
12-14-2006, 03:09 AM
On the main page (the page that holds the image) add the image node, and hide it via css, also give it an id so you can access
it from the onsubmit event later on.

This code would be added to the page where the form is located, below the </form> tag inside some javascript tags obviously ;D




/* the form */

var form = document.getElementById('upload_form');

/* we set the form onsubmit event */

form.onsubmit = function() {

/* img is the image that is supposed to be loaded on the main page, modify the id so your image node is returned */

var img = parent.document.getElementById('image');

/* you probably already have a way to figure out the path to the file on the server , if so you can ignore this */

filename = document.getElementById('upload_file').value;
filename = filename.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/);
filename = filename[2];

/* img onerror is triggered when the image could not be loaded, we make it try to reload the image on error, this can be load heavy i guess depending how long it takes for the image to upload, but you could also utilize a timer to handle this instead of having onerror handle it directly */

img.onerror = function() {
var pNode = this.parentNode;

/* new image node is

var img = document.createElement('img');

/* new image node attempts to load source, events are copied over */

img.src = this.src;
img.onerror = this.onerror;
img.onload = this.onload;
img.style.visibility = 'hidden';

/* insert new image node in place of old image node */

pNode.insertBefore(img, this);
pNode.removeChild(this);

img.id = this.id;
};

/* onload is triggered on success, we make the image visible */

img.onload = function() {
this.style.visibility = 'visible';
};

/* initial load */

img.src = filename;
};


As i said this might be load heavy, but it should give you an idea, and it shouldnt be a problem to do this with a timer instead. Man, been a while since i worked with frames :D Sorry it took so long, server gave me troubles.

codegreen
12-14-2006, 04:03 AM
Thanks alot, vegu.
I'll give it a try.

vegu
12-14-2006, 04:23 AM
Well, im back, the thing with the last example is , ie does not like it one bit, although ie still gives me trouble, and i cant figure why here is the new code, at least it doesnt result in error messages in ie

on the page that holds the image file add this



ImgTimer = null;

/* function loadimage */

function loadimage(filename) {

/* img = the image node on this page that you want to load
* the image in, edit id so it returns your image node
*/

var img = document.getElementById('image');

/* if this is the first try attempt to load image, and make the image invisible so
* we dont see the ugly broken image icon then bail */

if(img.isNewTry || img.isNewTry === undefined) {
img.src = filename;
img.isNewTry = false;
img.style.visibility = 'hidden';
return;
}

/* if image loading as not failed yet bail */

if(!img.failed)
return;

/* reload image */

img.src = filename + '?'+newDate().getTime();

};

var img = document.getElementById('image');

/* set on error event */

img.onerror = function() {
this.failed = true;
};

/* set onload event */

img.onload = function() {
this.isNewTry = true;
this.style.visibility = 'visible';
ImgTimer = clearInterval(ImgTimer);
};

/* the timer function that calles load_image */

function start_img_timer(filename) {
ImgTimer = setInterval(
function() { loadimage(filename); },
1000
);
}


This is the code that needs to be on the page with the form:



var form = document.getElementById('upload_form');
form.onsubmit = function() {
filename = document.getElementById('upload_file').value;
filename = filename.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/);
filename = filename[2];

/* init image load timer on main page */

parent.start_img_timer(filename);
};


Now the problem with IE is that it keeps firing the onerror function for somereason even after the image is accessable. Appearently it does try to reload the image else onerror would not be fired continually.

Nevermind! thanks to this article (http://www.irt.org/script/416.htm) ive fixed it and it should now work cross-browser :D

codegreen
12-14-2006, 11:34 AM
thanks again vegu



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum