Trying to access a JavaScript variable in one frame from another frame.

R

Rob

I know, I know, don't use frames. Well, I'm stuck with these frames and
I'm trying to add functionality without a complete redsign. You can
look at this as a nostalgic journey.

Anyway, I've got the following frame structure at the top level:

FRAMESET CODE
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html><head><title>Server List</title></head>
<frameset frameborder="1" border="1" framespacing="1" rows="10%,89%">
<frame name="TopFrame"
src="/rob/serverlist.nsf/TopPage?OpenPage"
SCROLLING="No" NORESIZE FRAMEBORDER="No">
<frameset cols="16%,83%">
<frame name="LeftNavFrame"
src="/rob/serverlist.nsf/LeftNavPage?OpenPage&amp;BaseTarget=MainFrame"
SCROLLING="No" NORESIZE FRAMEBORDER="No">
<frameset rows="8%,91%">
<frame name="ViewControls"
src="/rob/serverlist.nsf/by%20Server%20Name?OpenPage&amp;BaseTarget=MainFrame"
SCROLLING="No" NORESIZE FRAMEBORDER="No">
<frame frameborder="0" name="MainFrame"
src="/rob/serverlist.nsf/by%20Server%20Name?OpenView">
</frameset>
</frameset>
</frameset></html>

I'm trying to pickup the value of a JavaScript variable I set in one
frame from another frame. Here's the details.

In frame 'MainFrame' I have this code (it makes use of prototype.js to
fetch field values but that part of the code works. It just can't seems
to find code across frames.):
MAINFRAME CODE FRAGMENT

....snip
<body text="#000000" bgcolor="#E0FFFF" id='viewbody'>
<form action="">
<script>var resort = 'RESORT VALUE HERE';</script>
....snip

END MAINFRAME CODE FRAGMENT

In frame 'ViewControls' I have this code:
VIEWCONTROLS CODE FRAGMENT

....snip
<script>
function getFrame(fName){
var frames = top.document.getElementsByTagName("FRAME");
var frame= null;
for(var i=0; i < frames.length; i++){
if(frames.name == fName)
frame = frames;
}
var forms = frame.getElementsByTagName("*");
for(var j=0; j < forms.length; j++){
alert("Got form " + j);
}
// for(var n in frame.document.forms[0]){
// alert("Frame val: " + n + " is " +
frame.document.forms[0][n]);
// }
return null;
}

var viewStart = 1;
function openView(increment){
viewStart = parseInt(viewStart) + parseInt(increment);
viewStart = (viewStart < 1) ? 1 : viewStart;
alert("Frame found: " +
getFrame("MainFrame").document.forms[0].resort);
window.open($F('URLtoOpen') + "&Start=" + viewStart + "&Count="
+
$F("Count"), 'MainFrame');
}

</script>
Rows to display:
<input name="Count" value="1000" id="Count" size="4" maxlength="4">
<input type="button" onclick="viewStart=1;openView(0);" value="First
Page">
<input type="button" onclick="openView(-($F('Count')));"
value="<<Previous Page">
<input type="button" onclick="openView($F('Count'));" value="Next
Page>>">
<script>openView(0);</script>
....snip

END VIEWCONTROLS CODE FRAGMENT
So the function openView is called when the ViewControls page loads and
when one of the three buttons is pressed. Right now openView calls
getFrame("MainFrame") in the alert because I'm testing. getFrame
successfuly finds "MainFrame" but there I get stuck.

The DOM still confounds me after reading and working with it (on and
off) for months. I can not figure out what the hierarchy is of the
elements. When I use the DOM inspector in FireFox it shows me that
inside the FRAME with name="MainFrame" is "# document" (what does the #
mean?). I can trace through the children "document->HTML->BODY->FORM'.
Isn't this the form where the variable was created? Yet I can not find
it using the DOM inspector and I've tried everything I can think of in
the code to find it.

Clearly I am confused about the scope of things in the DOM. Can anyone
point me to a book or web site that CLEARLY explains what is where and
why? (Or any other help.)

Thanks in advance,

Rob:-]
 
A

ASM

Rob a écrit :
I know, I know, don't use frames. Well, I'm stuck with these frames and
I'm trying to add functionality without a complete redsign. You can
look at this as a nostalgic journey.

Anyway, I've got the following frame structure at the top level:

FRAMESET CODE
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html><head><title>Server List</title></head>
<frameset frameborder="1" border="1" framespacing="1" rows="10%,89%">
<frame name="TopFrame"
src="/rob/serverlist.nsf/TopPage?OpenPage"
SCROLLING="No" NORESIZE FRAMEBORDER="No">
<frameset cols="16%,83%">
<frame name="LeftNavFrame"
src="/rob/serverlist.nsf/LeftNavPage?OpenPage&amp;BaseTarget=MainFrame"
SCROLLING="No" NORESIZE FRAMEBORDER="No">
<frameset rows="8%,91%">
<frame name="ViewControls"
src="/rob/serverlist.nsf/by%20Server%20Name?OpenPage&amp;BaseTarget=MainFrame"
SCROLLING="No" NORESIZE FRAMEBORDER="No">
<frame frameborder="0" name="MainFrame"
src="/rob/serverlist.nsf/by%20Server%20Name?OpenView">
</frameset>
</frameset>
</frameset></html>

I'm trying to pickup the value of a JavaScript variable I set in one
frame from another frame. Here's the details.

In frame 'MainFrame' I have this code (it makes use of prototype.js to
fetch field values but that part of the code works. It just can't seems
to find code across frames.):
MAINFRAME CODE FRAGMENT

...snip
<body text="#000000" bgcolor="#E0FFFF" id='viewbody'>
<form action="">
<script>var resort = 'RESORT VALUE HERE';</script>
...snip

END MAINFRAME CODE FRAGMENT

In frame 'ViewControls' I have this code:
VIEWCONTROLS CODE FRAGMENT

...snip
<script>
function getFrame(fName){
var frames = top.document.getElementsByTagName("FRAME");

var frames = top.frames;
var frame= null;
for(var i=0; i < frames.length; i++){
if(frames.name == fName)
frame = frames;
}
var forms = frame.getElementsByTagName("*");


var forms = frame.document.forms;
or
var forms = frame.document.getElementsByTagName("*");
but will not be your forms (all tags)
so :
var forms = frame.document.getElementsByTagName("FORM");
^^^^^^^^ ^^^^
for(var j=0; j < forms.length; j++){
alert("Got form " + j);

alert('got tag '+j+' - tagname = '+forms[j].tagName);

}
// for(var n in frame.document.forms[0]){
// alert("Frame val: " + n + " is " +
frame.document.forms[0][n]);

non sense : you don't know if you are in a form
(could be body or div or...)
// }
return null;
}

[snip]
 
R

Rob

I've messed up my code trying to get something to work. I tried your
code like this:

function getFrame(fName){
var frames = top.document.getElementsByTagName("FRAME");
var frame= null;
for(var i=0; i < frames.length; i++){
if(frames.name == fName)
frame = frames;
}
var forms = frame.document.forms;
alert("Got this many forms: " + forms.length); // Should be one
un-named form
return null;
}

On this line: var forms = frame.document.forms
I get the error message, "frame.document has no properties".
That is my problem in a nutshell. The DOM inspector shows that frame
has one property it labels as "# document". (What does the # mean?)

That's where I'm stuck.

Thanks for helping.

Rob:-]
 
R

Richard Cornford

Rob said:
I've messed up my code trying to get something to work. I
tried your code like this:

function getFrame(fName){
var frames = top.document.getElementsByTagName("FRAME");
var frame= null;
for(var i=0; i < frames.length; i++){
if(frames.name == fName)
frame = frames;
}
var forms = frame.document.forms;
alert("Got this many forms: " + forms.length); // Should be one
un-named form


You want to watch letting your posting software wrap your code, as that
tends to render it syntactically incorrect (so we cannot tell whether
the incorrectness is in the original or an artefact of poor posting
style). Generally, arranging that posted code has no lines longer than
(about) 72 characters (and is indented with (2 to 4) spaces rather than
tabs) will avoid problems.
return null;
}
<snip>

Window/global objects (in browsers that support frames) have a -
frames - collection, in which the global/window object of all contained
frames can be referenced by NAME attribute or integer index. So
referencing the window/global object of a frame named 'LeftNavFrame' in
the top frame (the frameset page) from within any contained frame (or
the top frame itself) could be as simple as - frame =
top.frames['LeftNavFrame']; -. The resulting reference to the frame's
window/global object will be a reference to an object with a -
document - property that contains the document for that frame.

Richard.
 
R

Rob

Richard said:
Rob wrote:
You want to watch letting your posting software wrap your code, as that
tends to render it syntactically incorrect (so we cannot tell whether
the incorrectness is in the original or an artefact of poor posting
style). Generally, arranging that posted code has no lines longer than
(about) 72 characters (and is indented with (2 to 4) spaces rather than
tabs) will avoid problems.

Thanks for the tip on posting. I'll try to be more careful in the
future.

Window/global objects (in browsers that support frames) have a -
frames - collection, in which the global/window object of all contained
frames can be referenced by NAME attribute or integer index. So
referencing the window/global object of a frame named 'LeftNavFrame' in
the top frame (the frameset page) from within any contained frame (or
the top frame itself) could be as simple as - frame =
top.frames['LeftNavFrame']; -. The resulting reference to the frame's
window/global object will be a reference to an object with a -
document - property that contains the document for that frame.

Thanks for the tip about finding the frame. However, as I said in my
post, finding the frame isn't the problem. The code I posted above does
find the frame. What I can't seem to find is the document in the frame
or any form in the frame. As I said abouve, that's where I'm stuck.

So here's a quote from my original post which states more clearly where
I'm stuck and what I'd like in the way of help. I would really like to
find some documentation on the DOM that clearly tells me what you told
me and all the other things about the DOM that I don't understand
without having to beg for help on usenet. I've become skilled at many
aspects of programming but the DOM still eludes me somehow.

Rob wrote:
So the function openView is called when the ViewControls page loads and
when one of the three buttons is pressed. Right now openView calls
getFrame("MainFrame") in the alert because I'm testing. getFrame
successfuly finds "MainFrame" but there I get stuck.

The DOM still confounds me after reading and working with it (on and
off) for months. I can not figure out what the hierarchy is of the
elements. When I use the DOM inspector in FireFox it shows me that
inside the FRAME with name="MainFrame" is "# document" (what does the #
mean?). I can trace through the children "document->HTML->BODY->FORM'.
Isn't this the form where the variable was created? Yet I can not find
it using the DOM inspector and I've tried everything I can think of in
the code to find it.

Clearly I am confused about the scope of things in the DOM. Can anyone
point me to a book or web site that CLEARLY explains what is where and
why? (Or any other help.)
<snip>

Peace, Love, Laugher,

Rob:-]
 
R

Richard Cornford

Rob wrote:
Thanks for the tip about finding the frame. However,
as I said in my post, finding the frame isn't the problem.
The code I posted above does find the frame.

No it does not. The - top.document.getElementsByTagName("FRAME"); - call
returns a collection of FRAME _elements_ in the top document, if you
what easy access to the documents contained in the frames you should go
through the window/global object for each frame, so through the -
frames - collection.
What I can't seem to find is the document in the
frame or any form in the frame.
<snip>

As your collection is a collection of FRAME elements you will not find
that they have - document - properties except where they do, and those -
document - properties may refer to the document that contains the
element (i.e. top.document) on browsers such as IE 5.

You will find browsers where the FRAME elements have a -
contentDocument - property that is a reference to the contained
document, but going through the - frames - collection is as consistent,
cross-browser and reliable a method as is available.

Richard.
 
R

Rob

Hi Richard,

Thanks for helping. I've got some questions below.

Richard said:
Rob wrote:


No it does not. The - top.document.getElementsByTagName("FRAME"); - call
returns a collection of FRAME _elements_ in the top document, if you
what easy access to the documents contained in the frames you should go
through the window/global object for each frame, so through the -
frames - collection.

Well I know I'm misunderstanding something. I though frames were frame
elements. I still don't understand what you are saying. Can you write a
code snippet that shows me how to return the value from an input with
id='GetThis' on a frame named MainFrame.
<snip>

As your collection is a collection of FRAME elements you will not find
that they have - document - properties except where they do, and those -
document - properties may refer to the document that contains the
element (i.e. top.document) on browsers such as IE 5.

You will find browsers where the FRAME elements have a -
contentDocument - property that is a reference to the contained
document, but going through the - frames - collection is as consistent,
cross-browser and reliable a method as is available.

Where is this documented so I can look it up.
 
R

RobG

Rob said:
Hi Richard,

Thanks for helping. I've got some questions below.



Well I know I'm misunderstanding something. I though frames were frame
elements. I still don't understand what you are saying. Can you write a
code snippet that shows me how to return the value from an input with
id='GetThis' on a frame named MainFrame.

Frames are HTML elements and also DOM objects. The
document.getElementsByTagName() method returns a collection, which is a
DOM object but it isn't a DOM element object or an HTML element.

<URL:http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-75708506>

e.g. (in the example I'll use divs because it's simpler, frames work the
same way for getElementsByTagName())

<html><title>Test getElementsByTagName</title>
<div id="firstDiv">here is a div</div>
<div id="secondDiv">here is another div</div>

<script type="text/javascript">
var divs = document.getElementsByTagName('div');
alert(
'There are ' + divs.length + ' divs'
+ '\nThe first has id ' + divs[0].id
+ '\nThe scond has id ' + divs[1].id
);
</script>
</html>

In the above, document.getElementsByTagName('div') returns a collection
of the two divs. A reference to the collection is assigned to the
variable 'divs'.

To access the first div, use divs[0] and to access the second use divs[1].

A collection is a bit like an array - it has a special length property
and the members can be accessed by index. If there is only one frame in
a document, then:

var f = document.getElementsByName('frame')

will return a collection with a length of one. To access that element,
use - f[0] - just like an array (but please remember, collections aren't
arrays).

Where is this documented so I can look it up.

Rather than using the document.getElementsByTagName() method, some
browsers (e.g. IE) have a document.frames collection which is similar to
other collections like document.images and document.links.

Unfortunately, the frames collection isn't part of the W3C DOM 2 HTML
specification and it isn't supported by all browsers - e.g. Firefox.

The properties of the HTMLDocument interface are here:

<URL:http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268>

There are a number of collections:

readonly attribute HTMLCollection images;
readonly attribute HTMLCollection applets;
readonly attribute HTMLCollection links;
readonly attribute HTMLCollection forms;
readonly attribute HTMLCollection anchors;


'frames' isn't among them.
 
R

RobG

RobG wrote:
[...]
A collection is a bit like an array - it has a special length property
and the members can be accessed by index. If there is only one frame in
a document, then:

var f = document.getElementsByName('frame')

will return a collection with a length of one. To access that element,
use - f[0] - just like an array (but please remember, collections aren't
arrays).

Forgot to mention that collections are also 'live'. If you add another
div, it is automatically added to the collection, you don't have to do
getElementsByTagName('div') again to update it:


<div id="firstDiv">here is a div</div>
<div id="secondDiv">here is another div</div>

<script type="text/javascript">

var divs = document.getElementsByTagName('div');

alert(divs.length); // Shows 2

var d = document.createElement('div');
document.body.appendChild(d);

alert(divs.length); // Shows 3

</script>


[...]
 
R

Richard Cornford

RobG wrote:
Rather than using the document.getElementsByTagName()
method, some browsers (e.g. IE) have a document.frames
collection

I was not proposing the use of the - document.frames - collection at all
(as it is not cross-browser), I was proposing the use of the global -
frames - collection. The - frames - collection (the global one or the
document one) are not related to - getElementsByTagName - at all as they
are collections of window/global objects not a collection of elements.
which is similar to other collections like document.images
and document.links.

Unfortunately, the frames collection isn't part of the W3C
DOM 2 HTML specification and

The W3C DOM specifications do not mandate any properties of the global
object in HTML web browsers.
it isn't supported by all browsers - e.g. Firefox.

The global - frames - collection is supported by all browsers that
understand frames, including Firefox. If that were not the case it would
not be the most consistent and cross browser method of accessing the
content of frames.

Richard.
 
R

RobG

Richard said:
RobG wrote:


I was not proposing the use of the - document.frames - collection at all
(as it is not cross-browser), I was proposing the use of the global -
frames - collection. The - frames - collection (the global one or the
document one) are not related to - getElementsByTagName - at all as they
are collections of window/global objects not a collection of elements.


The W3C DOM specifications do not mandate any properties of the global
object in HTML web browsers.


The global - frames - collection is supported by all browsers that
understand frames, including Firefox. If that were not the case it would
not be the most consistent and cross browser method of accessing the
content of frames.

Ah yes... oops :-x I guess that's what comes of never using them.

And to answer the OP's question: "Where is it documented":

Gecko DOM page:
<URL:http://developer.mozilla.org/en/docs/DOM:window.frames>

MSDN HTML and DHTML page:
<URL:http://msdn.microsoft.com/workshop/author/dhtml/reference/collections/frames.asp>
 
R

Rob

Thanks for your help. Especially RobG for pointing me to the Mozilla
Developers web site.

I now have working code and here it is:

function getFieldValueFromFrame(frameName, fieldId){
var frames = top.frames
for(var i=0, fl = frames.length; i < fl; i++)
if(frames.name == frameName)
return frames.document.getElementById(fieldId).value;
return "";
}

However this page,
http://developer.mozilla.org/en/docs/DOM:window.frames
Says, "DOM Level 0. Not part of specification" so I'm thinking that my
original code would be more W3C complient. But I was wrong. Here's that
non-working code:

function getFieldValueFromFrame(frameName, fieldId){
// var frames = top.frames
var frames = top.document.getElementsByTagName("FRAME");
for(var i=0, fl = frames.length; i < fl; i++)
if(frames.name == frameName)
return frames.document.getElementById(fieldId).value;
return "";
}

This give the error, "frames.document has no properties." This page
http://developer.mozilla.org/en/docs/DOM:window.frames says, "Returns
an array of the subframes in the current window" and "frameList =
window.frames; frameList is an array of frame objects".

This page
http://developer.mozilla.org/en/docs/DOM:element.getElementsByTagName
says, "Returns a list of the descendant elements of a given name on the
current element." Since both versions find the frame I'm look for, I
conclude that both are returning essencially the same data.

However I also conclude that the elements returned by
getElementsByTagName and the objects in window.frames are not exactly
the same. But what is the difference and where is this difference
documented? It is a part of my knowledge-base that is missing:)

Again, thanks for all your help.

Rob:-]
I know, I know, don't use frames. Well, I'm stuck with these frames and
I'm trying to add functionality without a complete redsign. You can
look at this as a nostalgic journey.

Anyway, I've got the following frame structure at the top level:

Clearly I am confused about the scope of things in the DOM. Can anyone
point me to a book or web site that CLEARLY explains what is where and
why? (Or any other help.)

Thanks in advance,

Rob:-]
 

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

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top