We help IT Professionals succeed at work.

linking frames without a first reload

barbara032497
on
Medium Priority
265 Views
Last Modified: 2013-12-25
I have a main questionnaire which has several sections with
lots of checkboxes etc. and which is in "frame1".  I have a navigation frame "frame2" which has links to the top of each section and also has the main submit button form the questionnaire.

problem - the user loads the frames and starts to check the checkboxes.  If they then navigate using the buttons in frame2 then the questionnaire frame reloads and jumps rather than just jumps ***only on the first one though*** after that everythings works ok.  Of course the reload loses all their selections that first time!

Is there some way to set up the frames and links to avoid this first reload?

thanks

-barbara
Comment
Watch Question

Commented:
If you want to jump from place to place in a document without reloading the document, you omit the document's name - instead of <A HREF="this.html#position>, simply use <A HREF="#position">

The problem is, if you're doing this among frames, you _must_ name the document in the top frame (to load it from the bottom frame), which causes the page to reload, dropping all the values.

Of course, you already know this ...

There is no HTML-only work-around to this (even if the top and bottom frame are different parts of the same page, the first click will cause the top frame to reload, though subseuqnet clicks _may_ not) - and so ... it's JavaScript time.

In the bottom document, you'll need a bit of Javascript to preserve the values the user has entered.  This should work:

First,in the BODY tag of the top frame, add this ...

<BODY onLoad="restoreValues()">

For each link in the bottom, add this ...

<A HREF="page.html#location" onClick="saveValues()">

In the <HEAD> of the document on the bottom of the screen, place this ...

var valArray

function saveValues(){
     var x=0;
     while(x < parent.frames[0].forms[0].elements.length){
        valArray[x] = parent.frames[0].forms[0].elements[x]
        x++
        }
     }

function retoreValues(){
     var y = 0
     while (y < parent.frames[0].forms[0].elements.length){
        parent.frames[0].forms[0].elements[y] = valArray[y]
        y++
        }
     }

What this will do is store the values from the first frame in a variable attached to the second frame the moment the user clicks a link.  The top frame will then reload, but immediately (probably before the user even notices it), all the information is restored to the form in the top frqame from the second frame's variable.










Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
Sounds like a workablesolution but I'm struggling to reference
the right bits...my page has the questionnaire at the topand
the navigation frame below so
     parent.frames[0] should be the contentframe
     parent.frames[1] should be the toolbar frame

Using the code suggested gives me the error
   Window.forms has no property indexed by '0'

I spent most of last night trying to work out how to reference
the frames/forms but failed.  Any help would be appreciated.  
I can up the value of the question for the extra hassle :-)

thanks for your speedy answer yesterday... this really is an
important fix.

-barbara

Commented:
DOH!

I left an important bit out of the object references - document (so that the script could access the content rather than the frame object.  And so ... change each object reference to ...

parent.frames[0].document.forms[0].elements.length
                ^^^^^^^^^

Also, the < in the script might be mistaken for an HTML tag initiator by some browsers (I've had this problem before)- so where I originally suggested this ....
     (y < parent.frames[0].document.forms[0].elements.length)
use this instead ...
     (y != parent.frames[0].document.forms[0].elements.length+1)

Same thing for the while() of x in the other function.

To avoid being a moron twice (<g>), I tested this script with the aforementioned changes, and everything works well.  One minor "bug" is that the first time the page loads, restoreValues() puts the word "null" in the first text box.  To cure that, add a HIDDEN to the form as the first input <INPUT TYPE="HIDDEN" NAME="nevermind"> - that should be ignored by the script (unless there's a variable $nevermind someplace) and will catch the "null" on the first load.

Commented:
Foiled again ... since this page is in text that isn't monospaced, the ^^^^^ in the above comment probably looks a little weird - doesn't highlight what I intended it to.  The significant addition to the object is the "document" bit.

Author

Commented:
Well, I'm half way there now.  The above code saves ok
to the valArray when a link is pressed (had to use the
new array command with netscape though) but the content
frame does not seem to be able to access the same
valArray ie. the array length on save looks fine, the
array length on the restore valArray is null.  A scope
problem... how do you reference the variables of
another frame?  You said you tried out the above and it
worked ok... probably something funny I'm doing!

gee, I'll be glad when this works.  I have a couple of
folk breathing down my neck for it!!

many thanks again... getting closer.

-barbara

Commented:
It's just me being a dope again <g>.  

Not all browsers will treat a variable in the parent document as a global variable to scripts in child frames.  (If they'd only get together and define a standard, things would be a lot easier for all of us) - and without that, you'll have to kludge a bit to create a place where the values can be stored in the bottom frame that will be accessible by a script in the top frame.

This is going to be ugly, but functional ...

In the bottom frame, you'll need to create a FORM with the same number of fields as the form in the top frame (field names and types are unimportant) - this will provide the permanent and accessible "holding place" that you need.  To make this invisible to the user, I suggest setting the bottom frame as SCROLLING="NO" and using a transparent graphic (or whatever else) to push the FORM fields off the screen.

... told you it was going to be ugly - but it'll work (and I really can't think of another method).

And now, use the following script bits ...

TOP FRAME --------------------------------------------------

make the BODY tag onLoad="restoreValues()"

add to the HEAD the following function

function restoreValues(){
var x = 0
while (x != parent.frames[0].document.forms[0].elements.length + 1){
parent.frames[0].document.forms[0].elements[x].value =
parent.frames[1].document.forms[0].elements[x].value;
x++
}
}

BOTTOM FRAME --------------------------------------------------

make each HREF tag onClick="saveValues()"

add to the HEAD the following function:

function saveValues(){
var x = 0
while (x != parent.frames[0].document.forms[0].elements.length + 1){
parent.frames[1].document.forms[0].elements[x].value =
parent.frames[0].document.forms[0].elements[x].value;
x++
}
}

-------------------------------------------------------------

Unlike the previous "solution", this will work for MSIE (since it doesn't have an array object) and the previous problem with "null" should be overcome.

Sorry for all the red herrings.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.