Google Answers Logo
View Question
 
Q: How to create and manage complex nested frameset in javascript ( Answered 5 out of 5 stars,   3 Comments )
Question  
Subject: How to create and manage complex nested frameset in javascript
Category: Computers > Programming
Asked by: paulv-ga
List Price: $200.00
Posted: 12 May 2005 10:32 PDT
Expires: 11 Jun 2005 10:32 PDT
Question ID: 520935
I'm in the middle of developing a complex frames-based website.  I'd
noticed some Geocities-hosted pages using a javascript which
dynamically writes the entire frameset in - this then means that
javascript controls can be used to 'show' or 'hide' a frame.  This is
nice because it is the only method I know which works pretty well
cross-browser.

You can see an example of this here (a random geocities hosted site):
http://www.geocities.com/chumps_53705/

Notice how the tab that controls the opening or closing is actually in
a third (16 pixel wide) frame.

I've taken the javascript as used by Geocities and cleaned it up and
simplified it a lot - you'll find it below. However it only works with
a single frameset.  I need it to work with a nested frameset like
this:

<frameset rows="80,16,160,* cols="*">
  <frame name="bannerFrame" src="">
  <frame name="TAB1" src="">
  <frame name="searchFrame" src="">
    <frameset rows="*" cols="200,16,200,16,*">
      <frame name="pane1" src="">
      <frame name="TAB2" src="">
      <frame name="pane2" src="">
      <frame name="TAB3" src="">
      <frame name="display" src="">
    </frameset>
</frameset>

OR - the same effect acheived with an additional nested frameset would
be acceptable:

<frameset rows="80,16,160,* cols="*">
  <frame name="bannerFrame" src="">
  <frame name="TAB1" src="">
  <frame name="searchFrame" src="">
    <frameset name="set2" rows="*" cols="200,16,*">
      <frame name="pane1" src="">
      <frame name="TAB2" src="">
        <frameset name="set3" rows="*" cols="200,16,*">
          <frame name="pane2" src="">
          <frame name="TAB3" src="">
          <frame name="display" src="">
        </frameset>
    </frameset>
</frameset>

I also need the final script to do a couple more things.

What I'd like is code which works in a similar way to the geocities
thing (see below for a link to cleaned up version I've done) BUT which
additionally a) works with a nested frameset and b) adds the following
functionality:

* I need to be able to target any one of the frames from a link in any other frame;
* if the targetted frame is 'collapsed' I also need the javascript to
be clever enough to open it for me.
* If a link is used to open or close a frame, I'd like the associated
'tab frame' to update the image accordingly.

You can see a demo of the effect I want here, and check out the source
to see the cleaned up / altered geocities script I used:

http://www.qedstudio.com/frames/

I did this in a very dumb way in about 5 mins to show (partially) the
effect I want from this script.  As you'll see if you look at the
code, although it looks fine, the frameset is actually being generated
3 times (!!) - which is bad.  But it does demonstrate to you what I'm
after.  As well as this fundamental problem, I also haven't figured
out how I'd be able to have a link in, say, the white frame which
could target the black frame (say), AND open it if neccesary, AND
change the image in the tab above to reflect the open/closed state of
the black frame.
Answer  
Subject: Re: How to create and manage complex nested frameset in javascript
Answered By: wildeeo-ga on 12 May 2005 17:16 PDT
Rated:5 out of 5 stars
 
Hi, paul. Thanks for your question.

I've got some code that seems to do what you want. I've rewritten and
commented it so it's much easier to understand.

You can download it from http://hexx.net/ga/frameset.zip


A few notes about my version:


- The frameset that's written to the document initially is (almost)
the same one that you supplied as the first example of a nested
frameset. I removed the borders and changed a few of the names and
ids, but it's the same layout.


- It now uses cookies to store the open and closed tabs, and this
information should persist for a year. (You mentioned it on your
example page, and it wasn't too hard to implement). If you don't want
this functionality, you can comment out the following lines:
   
   
   var framesetCookie = getCookie('fscookie');
   
   saveCookie();
   
   
wherever they occur in the code. This will made the default frames
appear whenever a user visits.


- You can change the default frames shown by changing these lines (near the top):


   var searchFrameVisible = true;
   var listFrameVisible = true;
   var refineFrameVisible = false;
   
   
- Links can either open in a frame and expand it, or open in a frame
and keep it in the same state it was in before.

Firstly, the frame names I've used:

bannerFrame - the topmost banner frame (light blue in the example)
searchTabFrame - the frame for the search expansion tab
searchFrame - the search frame (black in the example)
listFrame - the left pink expandable frame
listTabFrame - the tab to open and close the left expandable frame
refineListFrame - the right pink expandable frame
refineListTabFrame - the tab to open and close the right expandable frame
displayFrame - the big content frame

If you want to change one, you can search and replace any of the names
above. You need to replace every occurrence in the frameset.js file,
and update the names of the expandable frames in the tab HTML files.

To open a link in a frame without expanding it, use the following:

<a href="[the url]" target="[frame name]">link</a>


To open a link in a frame and expand it if possible, use:

<a href="#" onClick="top.goToURL('[frame name]', '[the url]');return
true;">link</a>


Where [frame name] is the name of the frame from the list above, and
[the url] is the address. I've included a few examples in the package.


If I've misunderstood something or you have any questions, please
don't hesitate to request a clarification.

--wildeeo

Request for Answer Clarification by paulv-ga on 13 May 2005 02:03 PDT
Hi there - thanks for a really fantastic and clear response.  I'm
really pleased with the way this is working - may have to work on the
aesthetics ;)

Have a few questions, a collection of queries about extensibility
which I guess might not be so straightforward to answer.  Some of this
is wishlist stuff and I think if you're able to clarify anything much
we'd be moving into tip territory.  Anyway:

1. Is it possible to have a link which will open / close all the
frames at once? I can see how this might work as an extension of the
goToUrl function if necessary

2. I'm probably going to externalise some of the variables,
particularly the src attributes, since I'm going to need to use this
script for several different areas of the site.  Would it be easy to
pass the src attribute values to the script in a query string or
similar, such that the src vars you've set get overwritten by anything
passed, otherwise they act like default values?

3. With the frame sizes - again would it be possible to have a link
which could alter the dimensions of the 'content' frames (why? 
Because I'd like to tie this in with a font resizing option if poss). 
If this is easy then could the height / width vars be stored in the
cookie?

4. Is there a smart way to make the entire 'refineList' Frame optional
(other than just commenting it out)? It won't always be needed.

5. And finally...how difficult would it be to alter the goToURL
function so that instead of using a JS call in the anchor tag, the
href="" could be used normally and the target frame could be specified
using either the target="" or class="" attributes (with special
keywords, i.e. like class="tgtRefineList [other class(es)]").  Guess
the best solution would be if the href and target values could be
assigned in the 'normal' way, with a JS DOM function parsing through
and doing the necessary to make them work in the way that goToURL()
does now...what do you think?!

If you just want to give up now I'd quite understand!  Many thanks.

Clarification of Answer by wildeeo-ga on 13 May 2005 09:01 PDT
Hi,

Everything you've listed seems possible... I'll see what I can come up with.

Clarification of Answer by wildeeo-ga on 13 May 2005 11:22 PDT
Hi,

I've posted the revised version at http://hexx.net/ga/frameset_ii_the_revenge.zip


1: I've added a pseudo-frame '_all', and modified the goToURL method a
accept a third optional parameter. Now, the first parameter is the
frame to send the link to (and the frame to expand if the third is
omitted), the second is the link, and the third parameter is the frame
to expand.

You can also use the '_none' pseudo-frame to go to a link without
expanding anything not already expanded.


2 & 4: I've added query string support to it. The possible variables are:

bh - Banner frame height
sh - Search frame height
lw - List frame width
rw - Refine frame width

ban - Banner frame source (a warning about this; if someone felt like
it, they could simply do bla.html?ban=about:blank to hide the banner.
You may want to disable this).
search - Search frame source
list - List frame source
refine - Refine frame source
display - Display (main frame) source

norefine - If this is set to 1 (or to anything, really; the script
just checks it's been set) the refine frame is hidden.


3: You can either do this with query strings above, or using the new
resizeFrame method:

top.resizeFrame([frame name], [new size]);

The new size information will be stored in the cookie.


5: To handle this, I've created a new script called docreformat.js.
Use it simply by including it in the header:

<script src="docreformat.js" language="JavaScript"></script>

and it should automatically take care of reformatting the page.

Links in the form of <a href="http://bla" target="frame"> are mapped
to goToURL('http://bla', 'frame');

It also supports a custom attribute, 'expand', which can specify a
different frame to expand. This is really only useful with the '_all'
pseudo-frame, and it would work like this:

<a href="http://bla" target="frame" expand="_all"> would map to
goToURL('http://bla', 'frame', '_all');



The changes have been tested and seem to work okay in Safari 2.0,
Internet Explorer 6, and Firefox 1.0.4.

--wildeeo

Request for Answer Clarification by paulv-ga on 13 May 2005 12:06 PDT
It gets better, this is absolutely fantastic - thanks so much.  One
final thing - I can expand a designated frame, resize a designated
frame, open all the frames, but unless I'm missing something I can't
close a designated frame / all the frames from a link? Sorry if I'm
being dumb...

Clarification of Answer by wildeeo-ga on 13 May 2005 12:14 PDT
Hi,

You can do:

top.hideFrame('[whichever frame]');

to hide a frame. This also supports '_all', so:

top.hideFrame('_all');

should close every frame. There's also a function toggleFrame which
works in the same way to close an open one or open a closed one.

Request for Answer Clarification by paulv-ga on 13 May 2005 12:16 PDT
Yep, just seen that.  Sorry for being dumb

Clarification of Answer by wildeeo-ga on 13 May 2005 12:22 PDT
No problem. Glad I could help. :-)
paulv-ga rated this answer:5 out of 5 stars and gave an additional tip of: $75.00
Excellent and very quick solution to my problem.  Researcher
understood exactly what I was after and also answered my numerous
additional requests.  Absolutely first class.

Comments  
Subject: Re: How to create and manage complex nested frameset in javascript
From: its_vippy-ga on 31 May 2005 23:16 PDT
 
Hey wideeo or Paul
I am newbie to this whole Javascript thing
and need a same frameset as u ppl were discussing
but i was unable to download from www.hexx.net
Please help
Subject: Re: How to create and manage complex nested frameset in javascript
From: paulv-ga on 01 Jun 2005 00:37 PDT
 
Hi there, the links above are actually working for me but if you
coninue to have problems getting it then let me know and I'll pop the
two versions of the script online somewhere else.
Subject: Re: How to create and manage complex nested frameset in javascript
From: its_vippy-ga on 01 Jun 2005 18:15 PDT
 
Hi Paul
links not working for me
the server returns a invalid response.
Can you please pop them @ some other place.
Vipin

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy