/    Sign up×
Community /Pin to ProfileBookmark

Function not defined in onload

Hello and greetings,

I got a problem with the “onload-event handler” of “window”. This is the important part of my code:

[CODE]var name = “jack”;
var newWin = window.open(“assets/new.html”, … , …);
newWin.onload = function() { testFunction(name); }[/CODE]

It is supposed to open a new window, load some html-file into it and AFTER completion execute a function named “testFunction(text)” defined in the same script.
But the console all the time says “testFunction not defined”.

I have also tried to do a call to “window.opener.testFunction(window.opener.name);” within the “onload-function”. But it doesnt work either :/

I’m so frustrated, because I tried for hours by now. What is the problem with my script?

Thanks in advance!

to post a comment
JavaScript

19 Comments(s)

Copy linkTweet thisAlerts:
@UltimaterMay 03.2006 — newWin.onload=function(){[color=blue]newWin.[/color]testFunction(name)}
Because the above is interchangeable with the following:
<i>
</i>function myFunction(){
newWin.testFunction(name)
}

newWin.onload=myFunction;
Copy linkTweet thisAlerts:
@rapthorauthorMay 05.2006 — [CODE]var name = "jack";
var newWin = window.open("assets/new.html", ... , ...);
newWin.onload = function() { newWin.testFunction(name); }[/CODE]


Okay this works! But it does not work every time! Sometimes, the command window.open is faster than specifying the onload function in the next line. So the result is, that the function in onload is NEVER called. :mad:

So, I could simply put in an additional line like this "newWin.testFunction(name);". But as you know, if it is the case, that window.open is very slow, this new line would give me the error, that the function "testFunction" in newWin isn't defined. Because the opened window didn't build completely.

[B]So how do I manage those two cases? In either one I want to call the function in the new opened window.[/B]

Thanks again.
Copy linkTweet thisAlerts:
@UltimaterMay 05.2006 — Untested:
<i>
</i>var name = "jack";
var newWin = window.open("assets/new.html", ... , ...);

var wasCalled=false;
newWin.onload = callFunc;
setTimeout(callFunc,100);
function callFunc(){
if(wasCalled)return;wasCalled=true;
if(!newWin.testFunction){wasCalled=false;return;}
mainFunc()
}

function mainFunc(){
newWin.testFunction(name)
}
Copy linkTweet thisAlerts:
@rapthorauthorMay 06.2006 — Hi,

thanks again but what do you intend to achieve by using "if(!newWin.testFunction){wasCalled=false;return;}"? I think I'm unsure about the effect of that. What does it mean to call "newWin.testFunction" without brackets?
Copy linkTweet thisAlerts:
@UltimaterMay 07.2006 — <i>
</i>if(newWin.testFunction)

without parenthesis in an if-statement is a test if the function exists but doesn't actually execute the function. For example:
<i>
</i>&lt;script type="text/javascript"&gt;
if(window.alert)alert("hi");//Alerts "hi"

if(window.aFunctionNotDefined){
alert("The function aFunctionNotDefined exists")
}
else{
alert("The function aFunctionNotDefined does not exist")
}
&lt;/script&gt;

newWin.testFunction, if it is defined, would return the code which defines it.
<i>
</i>&lt;script type="text/javascript"&gt;
function hi(){
alert("If you can read this, the function hi had been called.")
}
alert(hi); //alerts the code that defines the function hi.
&lt;/script&gt;

Since a "true" boolean value is anything which isn't 0, a blank string, null, or false,

a filled string, a number other than 0, the code defining a function, or an object would simulate and be treated as a "true" boolean value.


The intention of the code in my previous post was to be sure that the "mainFunc" function executes once, only once, at least once. Once it should be called and to call the "testFunction" function not before it exists, but only after it is defined in the pop up window.

If the ONLOAD event fired prior to assigning a function to it, your testFunction function wouldn't be called. So in case the ONLOAD event already fired, I had to give the testFunction function a call manually. The question then becomes "How does one test whether the ONLOAD event was fired yet?" My approach was to use a global variable "wasCalled" and initialize it to false. If the ONLOAD event fires before the 100 milliseconds elapse, the variable "wasCalled" is set to "true" so the setTimeout doesn't execute the "mainFunc" twice. If the setTimeout fires before the ONLOAD, it first checks to see if the function "testFunction" in the pop up window is defined yet. If it isn't defined, surely the ONLOAD event didn't fire. Thus, the function "testFunction" at this point in time still doesn't exist nor did the ONLOAD fuction fire. That is a good sign. So we wait for the ONLOAD to execute the mainFunc". To do this we set "wasCalled" to "false" so when the ONLOAD will later fire, it will execute the "newWin.testFunction(name)" as usual.


If this is still not 100% clear to you, please tell me what to elaborate-on so I can give some more example code.
Copy linkTweet thisAlerts:
@rapthorauthorMay 09.2006 — Okay, it's clear now ? thanks!

I got another problem now. The code you mentioned works fine, if i Put it in a function like this:

[CODE]function start()
{
var name = "jack";
var newWin = window.open("assets/new.html", ... , ...);

var wasCalled=false;
newWin.onload = callFunc;
setTimeout(callFunc,100);
function callFunc(){
if(wasCalled)return;wasCalled=true;
if(!newWin.testFunction){wasCalled=false;return;}
mainFunc();
}

function mainFunc(){
newWin.testFunction(name);
}
}[/CODE]


Exactly the same code placing into antoher function does not work. This function is looking similar to this one:

[CODE]function anotherOne()
{
...
...
var sure = confirm("Really execute?");
if (sure)
{
var name = "jack";
var newWin = window.open("assets/new.html", ... , ...);

var wasCalled=false;
newWin.onload = callFunc;
setTimeout(callFunc,100);
function callFunc(){
if(wasCalled)return;wasCalled=true;
if(!newWin.testFunction){wasCalled=false;return;}
mainFunc();
}

function mainFunc(){
newWin.testFunction(name);
}
}
else
......
}[/CODE]


So the only "big" difference is, using your code inside an if-construction, so it seems.

The error I get is [B]"callFunc is not defined"[/B] on this line:

"newWin.onload = callFunc;".

So I thought placing the definitions of the two inline functions BEFORE that onload-assignment will fix it. But after changing the order I get another message: [B]"name has no properties"[/B]. This is the line mentioned within the inline-function called "function mainFunc()":

"newWin.testFunction(name);".

This means "name" is undefined (Firefox uses this error message).

[B]I don't get, why the same code is working above, but not in the second case![/B]

Can you help me again, please? ?
Copy linkTweet thisAlerts:
@UltimaterMay 09.2006 — The code you mentioned works fine, if i Put it in a function like this:

[CODE]function start()
{
var name = "jack";
var newWin = window.open("assets/new.html", ... , ...);

var wasCalled=false;
newWin.onload = callFunc;
setTimeout(callFunc,100);
function callFunc(){
if(wasCalled)return;wasCalled=true;
if(!newWin.testFunction){wasCalled=false;return;}
mainFunc();
}

function mainFunc(){
newWin.testFunction(name);
}
}[/CODE]

[/QUOTE]

The code is not intended to be used like that, even if it [i]does[/i] work.

mainFunc and callFunc should be declared globally -- not within another function.

In otherwords:
<i>
</i>&lt;script type="text/javascript"&gt;
function callFunc(){
if(wasCalled)return;wasCalled=true;
if(!newWin.testFunction){wasCalled=false;return;}
mainFunc();
}

function mainFunc(){
newWin.testFunction(name);
}

function start()
{
name = "jack";
newWin = window.open("assets/new.html", ... , ...);
wasCalled=false;
newWin.onload = callFunc;
setTimeout(callFunc,100);
}
&lt;/script&gt;

Also note that I have removed all "var" instances so as-to declare the needed varaibles globally and not locally so that other functions can access them.

Assuming you first code worked and your 2nd code didn't, I believe the reason is because of the time delay of the user hitting "OK" on the confirm.

To verify if this is the reason, try replacing:
<i>
</i>var sure = confirm("Really execute?");

with:
<i>
</i>var sure = true;

If it still gives an error, maybe your initial first code didn't work either -- like I'd expect (seeing as the functions and variables should be defined globally).
Copy linkTweet thisAlerts:
@rapthorauthorMay 09.2006 — Ah, well I understood. But may it be possible that the timeout set to 100 ms is too short to work on slow http connections? Assuming the new window contains many lines of HTML code, the "onload"-event would be fired later.


Assuming you first code worked and your 2nd code didn't, I believe the reason is because of the time delay of the user hitting "OK" on the confirm.[/QUOTE]
Copy linkTweet thisAlerts:
@UltimaterMay 09.2006 — The function that the setTimeout calls needs to be declared globally.
Copy linkTweet thisAlerts:
@rapthorauthorMay 09.2006 — I will test that.

I'm glad to have a user like you, that is concerning with my "problems". Thanks a lot!
Copy linkTweet thisAlerts:
@rapthorauthorMay 10.2006 — Hm ... it is mysterious somehow.

Although making the functions and variables global, it does not seem to work for the second case.

May the reason be using "window.open();" in an AJAX response function? (It is the function called, when the response of the request is going in.)

[CODE]
// global definitions for onload variables
var name = "jack";
var newWin;
var funcWasCalled = false;

....
....

function submitAJAXRequest()
{
req = getXMLObject();
if (req) {
req.open ("POST", "someURL.htm", true);
req.setRequestHeader("Content-Type", requestheader);
req.send(null);
req.onreadystatechange = [B]getAJAXRequestResult[/B];
clearErrorMessage();
}
}

// here is window.open()
function [B]getAJAXRequestResult() [/B]{
if (req.readyState != 4)
return;
......
......
[B] var showSummary = confirm("yes or no");
if (showSummary)
{

funcWasCalled = false;
newWin = window.open("packing.html", "", "", 660, 700);
setTimeout(callFunc,100);
newWin = callFunc;
}[/B]
}

// global definitions for the onload functions
function callFunc()
{
if(funcWasCalled)
return;
funcWasCalled=true;
if(!newWin.testFunction)
{
funcWasCalled=false;
return;
}
mainFunc();
}

function mainFunc()
{

newWin.testFunction(name);
}
[/CODE]


The error I get is "funcWasCalled is not defined"! At this line in function "callFunc()":

if([COLOR=Red]funcWasCalled[/COLOR])
return;


As you can see, this variable is global ... so where's the mistake?
Copy linkTweet thisAlerts:
@UltimaterMay 10.2006 — <i>
</i> if (showSummary)
{ <br/>
funcWasCalled = false;
newWin = window.open("packing.html", "", "", 660, 700);
setTimeout(callFunc,100);
newWin[color=blue].onload[/color] = callFunc;
}
Copy linkTweet thisAlerts:
@rapthorauthorMay 10.2006 — Sorry, in deed there is a "newWin.onload = callFunc;". Copy/Paste error!

The problem remains the same ?
Copy linkTweet thisAlerts:
@rapthorauthorMay 10.2006 — I tried to move the code out of the AJAX response function. It works, but I wanted to be able to open a new window from within that function somehow.

If you don't know a solution for that, don' worry. You helped me a lot, already! Thank you.
Copy linkTweet thisAlerts:
@UltimaterMay 10.2006 — Try re-ordering these two:
<i>
</i>req.send(null);
req.onreadystatechange = getAJAXRequestResult;
to:
<i>
</i>req.onreadystatechange = getAJAXRequestResult;
req.send(null);


and changing:
<i>
</i>if (req.readyState != 4)return;

to:
<i>
</i>if (req.readyState != 4 ||req.status != 200)return;


and removing the optional:
<i>
</i>req.setRequestHeader("Content-Type", requestheader);


and changing:
<i>
</i>req.open ("POST", "someURL.htm", true);

to a GET request:
<i>
</i>req.open ("GET", "someURL.htm", true);


I assume you are using Ajax because you plan to later make use of [b]req.responseText[/b]. which I don't see anywhere
Copy linkTweet thisAlerts:
@rapthorauthorMay 11.2006 — Try re-ordering these two:
<i>
</i>req.send(null);
req.onreadystatechange = getAJAXRequestResult;
to:
<i>
</i>req.onreadystatechange = getAJAXRequestResult;
req.send(null);
[/QUOTE]


This does not resolve it. In fact I'm using req.send(encodeURI("parameter=" + xyz)); instead of req.send(null). (Just to give you a short summary, I thought I will cut that out).


and changing:
<i>
</i>if (req.readyState != 4)return;

to:
<i>
</i>if (req.readyState != 4 ||req.status != 200)return;

[/QUOTE]


If I use that, my "getAJAXRequestResult;" is always returning and never processing completely.


and removing the optional:
<i>
</i>req.setRequestHeader("Content-Type", requestheader);

[/QUOTE]


Unfortunately I have to specify the "Content-Type" like "application/x-www-form-urlencoded; charset=UTF-8 ". In my application it is not req.send(null) but req.send(encodeURI("parameter=xyz"));.

If I leave out this customized content-type, the server does not receive any parameters.

It was quite puzzling to me to find that solution, because before a few weeks I had to use Ethereal to spy ethernet traffic in order to see what content type is sent, when using standard HTML-FORMs. I just copied that content-type and put it in there: req.setRequestHeader("Content-Type", requestheader);. From then on, it worked fine ...


and changing:
<i>
</i>req.open ("POST", "someURL.htm", true);

to a GET request:
<i>
</i>req.open ("GET", "someURL.htm", true);


I assume you are using Ajax because you plan to later make use of [b]req.responseText[/b]. which I don't see anywhere[/QUOTE]


Using "GET" instead of "POST" isn't possible because I get the same error as if I would leave out the content-type -> the submitted parameter is not recognized.

You were right: req.responseText is used later on. I left that part out of the posted code to give a short example of what I mean.

So, finally the problem of opening a new window and dynamically extending its content remains. There is still that error saying "funcWasCalled is not defined".

Just to give you the code I'm using now:
[CODE]
function doAJAXRequest()
{
.....
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.overrideMimeType('text/xml');
}

if (req) {
req.open ("POST", "someTomcatURL", true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8 ");

req.onreadystatechange = getAJAXRequestResult;
req.send(encodeURI("requestXML="+xml));
}
.....
}

function getAJAXRequestResult()
{

if (req.readyState != 4)
return;
......
// the window.open(...)-thing
......
}
[/CODE]
Copy linkTweet thisAlerts:
@UltimaterMay 11.2006 — 

and changing:
<i>
</i>if (req.readyState != 4)return;

to:
<i>
</i>if (req.readyState != 4 ||req.status != 200)return;

[/quote]

If I use that, my "getAJAXRequestResult;" is always returning and never processing completely.
[/quote]

A status of 200 means the request was ok and if the status is not 200, then there was a problem in the request.

I suspect that the POST data is corrupted.

Try
<i>
</i>req.send("requestXML="+[color=blue]encodeURI(xml)[/color]);



req.open ("POST", "someTomcatURL", true);
[/quote]

Is whatever you have for "someTomcatURL" correct? It [i]must[/i] be located on the same domain. (i.e. without resorting to privilege enabling)
Copy linkTweet thisAlerts:
@rapthorauthorMay 11.2006 — A status of 200 means the request was ok and if the status is not 400, then there was a problem in the request.

I suspect that the POST data is corrupted.

Try
<i>
</i>req.send("requestXML="+[color=blue]encodeURI(xml)[/color]);

[/QUOTE]


Okay, I will try this on monday because this is the next time I've the chance to do so.

Isn't it supposed to be like "req.send([color=blue]encodeURI("requestXML="+xml)[/color]);" instead of "req.send("requestXML="+[color=blue]encodeURI(xml)[/color]);"?


Is whatever you have for "someTomcatURL" correct? It [i]must[/i] be located on the same domain. (i.e. without resorting to privilege enabling)[/QUOTE]


It's a URL mapped to a servlet (so it does not matter how you name it, due to you can map any path to any controller). In detail, it is the spring dispatcher servlet ([URL=http://en.wikipedia.org/wiki/Spring_framework]Spring Application Framework[/URL]) at first glance. From there on the request is forwarded to another servlet depending on the URL. Every servlet is in the same domain and on the same server.

Thank you so much and have a nice weekend .. I will have another try on monday.
Copy linkTweet thisAlerts:
@UltimaterMay 12.2006 — For debudding purposes, try this:
<i>
</i>function getAJAXRequestResult()
{
if (req.readyState != 4)return;//0:uninitialized, 1:loading, 2:loaded, 3:interactive, 4:complete


if (req.status == 200) {//200:"OK", 403:"Forbidden", 404:"File Not Found", etc
alert("Request OK:nn" + req.responseText);
} else {
alert("Request Problem:nn " + req.status+"nn"+req.statusText);
}

}
×

Success!

Help @rapthor spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 6.17,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @nearjob,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,
)...