Link to home
Start Free TrialLog in
Avatar of kereborn
kerebornFlag for Netherlands

asked on

setting the target of a form in an iframe or nested frames in Opera7

L.S.

I need to set an inputfield as well as the target of a form, which is placed in an iframe. This iframe, is yet in another normal frame. Now, I need a code which would be something like:

top.frame[x].iframe[x].document.form[x].element[x].value = value;
top.frame[x].iframe[x].document.form[x].target = target;
top.frame[x].iframe[x].document.form[x].submit();

I'd rather work not with an iframe at all, but I have to, since Opera7 seems to have bug that you cannot nest normal frames within normal frames and then target them, i.e. (IE5+ and NS7+ do not seem to have that problem. This code above works for these browsers):

elementId = "username";
formId = "loginform"

thisObj = eval("top.level1.level2.document.getElementById('"+elementId+"')");
thisObj.value = "valueOfElement";
thisObj = eval("top.level1.level2.document.getElementById('"+formId+"')");
thisObj.target = "targetFrame";
thisObj.submit();

So, does anyone know how to target the target of a form in an iframe in a frame ..... , or even better .....

know how to target nested frames in Opera7?

thanx, Kereborn
Avatar of amit_g
amit_g
Flag of United States of America image

Instead of frame and iframe use frames collection and in place of x give name of the frame or iframe. Do the same with form and element i.e. use forms and elements collection ...

top.frames["FrameName].frame["IFrameName"].document.forms["FormName"].elements["ElementName"].value = value;
top.frames["FrameName].frame["IFrameName"].document.forms["FormName"].target = target;
top.frames["FrameName].frame["IFrameName"].document.forms["FormName"].submit();

Make sure to give name attribute in each frame, iframe and form.

<frame name="FrameName" ...>
<iframe name="IFrameName" ...>
<form name="FormName" ...>
I had a missing " in the code. It should be

top.frames["FrameName"].frame["IFrameName"].document.forms["FormName"].elements["ElementName"].value = value;
top.frames["FrameName"].frame["IFrameName"].document.forms["FormName"].target = target;
top.frames["FrameName"].frame["IFrameName"].document.forms["FormName"].submit();
Avatar of kereborn

ASKER

Alas, it won't work. Somehow the target will not be set, resulting in a extra window being opened.

But I had already tried this code. That's why I wrote 'something like'. ;-)

Any other options? I'd really prefer the nested frames option in stead of an iframe within a frame. But Opera7 will not let this happen. Checking on IE6+.

Darn ...

It works on IE6+. Looks like nested frames (no matter if it's iframe or regular frame) will not work in Opera7.

Still, I have to make it happen in Opera7, since the security of IE sucks (damned ActiveX controls...)
What is the target that you are trying to set? Can we see it happening if it is on the net?
Yes, you can, but it is rather complex. Mixed perl code, lots of different files, etc. So, I'll put the functions here:

# top
<frameset>
  <frame name=frameO id=frameO>
  <frame name=zero id=zero>
</frameset>

# frameO
<frameset>
  <frame name=iFrameA id=iFrameA>
  <frame name=iFrameB id=iFrameB>
  <frame name=iFrameC id=iFrameC>
</frameset>

# this is iFrameA
<html>
  <head>
    <script>
      function Form(frame,form,target,action) {
        top.frames['frameO'].frames[frame].document.forms[form].elements['action'].value = action;
        top.frames['frameO'].frames[frame].document.forms[form].target = target;
        top.frames['frameO'].frames[frame].document.forms[form].submit();
      }
    </script>
  </head>
  <body onLoad="Form('iFrameA','Form','iFrameB','action1');Form('iFrameA','Form','iFrameC','action2');">
    <form id=Form name=Form method=post action=form.cgi target=zero>
      <input id=username name=username type=hidden value="">
      <input id=password name=password type=hidden value="">
      <input id=action name=action type=hidden value="">
    </form>
  </body>
</html>
Well ... I'll be monkey's uncle! Now the scripts that have not worked for over weeks of bloody testing actually do work! Same script, nothing has changed. Then it didn't, now it does work. AAARRRGGH. It has got to be something to do about:

<frame name=Blah id=Blah>

Then I tried that. Didn't work. Opera7 would not respond. Had to make it <name=> only. Couldn't use <id=>.

Now I've change that back, just to try once more to <id= name=>. It works fine now. (Can't wait to see what it will do in a few minutes.) Must be a virus. In my brain. Tells me that everything is really the same, when it was likely a typo, back then, after all?

Thanx amit_g anyway for trying to help me out. What do you reckon? Award you the point (for I solution I'd already tried) anyway?
Avatar of NetGroove
NetGroove

Hello Kereborn,

from your html code I see that you mix up the names for inner frames with special object IFRAME.

You can have an IFRAME inside one html page, undepended whether this page is inside a frame or top of window.

I would reduce your Form() function (dangerous name) to this:

    <script>
     function Form(frameName,formName,targetFrame,actionLink) {
       parent.frames[frameName].document.forms[formName].action = actionLink;
       parent.frames[frameName].document.forms[formName].target = targetFrame;
       parent.frames[frameName].document.forms[formName].submit();
     }
   </script>

Doing two submits of same form imediately one after the other will bring you also next problems.

Good luck,
NetGroove


One explanation why your former tests did not work and now work is tha fact that you address your frames from the top most frame.
If your top most frame is NOT your top frameset, then you loose your top reference.
Now is no frameset above your top frameset and it works again.

Using relative reference from the actual page with the parent object would help.

Oh, and the unvisible topmost frames are offten hidden framesests from free web hoster. Do you test on a free webhoster?

Not the problem here.

No no. The top is mine. No free hosting. I know what I'm doing here. All the framesets belong to me and my subdomain.domain.locator.
Ok, but as soon as your top.html is inside a frame your top.references will not work, but parent.referencess will work.

Also are some browsers not so tolerant using variables with the name "form"

function GetId(path,item) {
  pathEval = eval(path+".document.getElementById('"+item+"')");
  return pathEval;
}

thisObj = GetId(path,item);
thisObj.value = 'blah';
thisObj.etc

path could be something like 'top.frameA.frameB.frameEtc'
item would be any element in that frame, i.e. 'username' or 'password' or 'formA' etc.

Using this code again in nested frames. Got rid of the iFrames now. They're a nuisance.
Variable and functions names are not the issue. 'Form' != 'form', you know.

Parenting would be ok, but since I never know from what frame I'll be adressing an other frame, the parent.parent.parent construction will not work.

Why all this variable targetting stuff? Since I'm building a dynamic site tool in Perl. But all the different subdomains may have different layouts. One might have 1 frame, whereas others might have 10 frames nested into one and other. All I know is the target frame, but not the source frame. So parent will not work, alas.
Did you think about some sort of GetId() function which would do a recursive traverse of frame tree to finde your searched frame by name?

Hmmm. Could work.

Now, I'm not a javascript programmer, so, would you have any ideas as how to do this? (I could find out myself, but will cost me too much time.)
ASKER CERTIFIED SOLUTION
Avatar of NetGroove
NetGroove

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Would this work as well? (My guess is: yes?)

function GetTarget(frameName,elementName) {
  thisTarget = window.open('',frameName).document.getElementById(elementName);
  return thisTarget;
}

thisObj = GetTarget('frameA','elementA');
thisObj.value = 'valueA';
thisObj = GetTarget('frameA','formA');
thisObj.target = 'frameB';
thisObj.submit();
Yes, I tested it just now, and it worked.

Only thing you have to be aware of is that in Netscape you need for every object that you want to access with your extended method also an object id.
My tests was positive in IE6.0 and NS7.1 when form tag hold also the id= attribute.
But it did work only in IE when id= attribute was removed and only name=  was in the form tag.


Great! Thanx. I'll test it in Opera7 as well, and implement it if it works.

Always thought that such a code would be more complex, involving for-next-loops to check the whle frames[] and forms[] arrays and such. Are you sure the open('','frameName') method is DOM approved?
No, it is not a Document Object Model method, it is simply how the most browsers implement the window.open() functionality.
Therefore it has to work also in browsers before DOM. But then without your extension.

Tested it and love it. In Opera7 it works excellent, even when absorbed in another frame. No more 'top.' references. Funny thing is, it doesn't work in IE this time.
I say only one word: typo :-)
Oh, just now I scanned your profile and your old questions.
I noticed that you searched for longer time for this solution.
How about five hundred points and an grade of  A++  for me :-)

Hmmm. Now it does. When it didn't, clear all the buffers and cache. Didn't work. Cleared them again. Didn't work. Counted to 10. Cleared them again and now IE behaves nicely as well.

Gawd, specifically set the cache options off, so that every reload is a real reload and it still caches it.
OK, that's fair ... well, almost. The others helped as well. All in all it seems (I REALLY cannot believe this, but is must be, although I checked, doubled checked and that again) a mere typo?

So all in all, it comes to this:

frames must be (just like elements) be defined by name= and id=

AND

no typo's

;-)

Oh well. Points coming your way for the nice subroutine. Thanks so much for wanting to think along my line.

cU again (I hope) and cheers, Kereborn
Thanks for the points (you did not increase them :(

See you,
NetGroove

OOOOooops. Sorry. [shame] Forgot. Can I reopen the question, add the bonus and then accept it again?
Hey, no problem.
As you said, there will be more questions to meet again.

So long,
NetGroove