9

I need to automate a web form which uses iframes to embed child 'forms' which can be considered as separate html pages.

So you get a parent document which contains what they call view fields which are iframes. Within the iframes are the 'child' embedded web pages.

A simple example:

I have cut out a lot off the html to reduce it to a reasonable size

<html>
<body>
  <div id="123" arid=123 artype="View" ardbn="vfMyChild" 
  class="arfid123 ardbnvfMyChild" 
STYLE="top:49 left:75 width:1038 height:322" arvfframe="&lt;iframe style=&quot;top:0 left:0 width:1038; height:322&quot name=&quot;VF123&quot;  title=&quot;View Field&quot; src=&quot;javascript:&amp;quot&#59;&amp;lt&#59;HTML&amp;gt&#59;&amp;lt&#59;/HTML&amp;gt&#59;&amp;quot&#59;&quot; &gt;
&lt;/iframe&gt;">
</div>

</body>
</html>

Then the embedded child html could be simple like this:

<html>
<body>
<div id="321" arid=321 artype="Char" ardbn="txtRegister">
   <label id="label321" class="label f6">Register:</label>
   <textarea id="arid_321" cols="20" maxlen=255 rows=1></textarea>
</div>
</body>
</html>

The html contained in the STYLE= looks a bit odd - not sure why it is like that. But I can see it is sort of an iframe.

I have an instance of the top level document object and I have an instance of the div with id=123. I need to automate the textarea object in the child. I tried the following which did not work.

var viewfields;  //is a ref to the div with id=123

if(viewfields) {
     window.alert("viewfields.length=" + viewfields.length);  //prints len=1 as expected
     // line below get Caught exception: Unable to get value of the 
     // property 'document': object is null or undefined
     var innerDoc = viewfields[0].contentDocument || viewfields[0].contentWindow.document;
     if(innerDoc) {
           window.alert("Wohoo we have an innerDoc");
     }
} else
      window.alert("no view fields found");

I am testing this using IE9.

Will I be able to get an instance of the inner web page with this html? If so, how?

EDIT

If it helps, here is the actual, unedited html for the div in question.

<div id="WIN_0_536870915" arid=536870915 artype="View" ardbn="vfCubaChildren"  class="arfid536870915 ardbnvfCubaChildren" STYLE="top:49&#59; left:75&#59; width:1038&#59;  height:322&#59;z-index:1001&#59;background-color:transparent&#59;" arvfframe="&lt;iframe  style=&quot;top:0&amp;#59&#59; left:0&amp;#59&#59; width:1038&amp;#59&#59;  height:322&amp;#59&#59;background-color: transparent&amp;#59&#59;&quot;  name=&quot;VF536870915&quot; frameborder=1 scrolling=&quot;auto&quot;  allowtransparency=&quot;true&quot; title=&quot;View Field&quot;  src=&quot;javascript:&amp;quot&#59;&amp;lt&#59;HTML&amp;gt&#59;&amp;lt&#59;/HTML&amp;gt&#59    ;&amp;quot&#59;&quot; onload=&quot;DVFol&amp;#40&#59;&amp;#41&#59;&quot;&gt;
&lt;/iframe&gt;">
</div>

That div holds the child form. The child form is like another html web page. It has standard html input fields and textarea's. I need to post text to the textarea's in the child (from the parent). But the problem is I cannot yet access the child html object from the parent.

Angus Comber
  • 9,316
  • 14
  • 59
  • 107
  • I probably don't recognize what you're working with, but what are the `arid`, `artype`, `ardbn`, and `arvfframe` element attributes specified? – Jesse Apr 13 '13 at 16:16
  • I thought you said viewfields was a `div` in an `iframe`, but you're treating it like an array? Also, it shouldn't affect your code, but you're missing quotes on some attributes. – Brian McCutchon Apr 13 '13 at 16:22
  • @Jesse arid etc are custom attributes used by the web application. web app is BMC Remedy if that helps. – Angus Comber Apr 13 '13 at 18:45
  • @user619818 Are you wanting to construct an `iframe` out of the markup inside of the `arvfframe` attribute? And then access a child object inside of that? – Jesse Apr 13 '13 at 23:25
  • @Jesse, I can access the parent iframe (containing child) - but what I can't seem to do is access the child object inside. Unfortunately doing a mockup is difficult. – Angus Comber Apr 17 '13 at 17:56

3 Answers3

8

If you are trying to get the data from the parent looking into the iframe then this is what you are looking for. Bare in mind that this only works if the iframe source is a page from the same domain, otherwise you wouldn't have the permission to access its contents.

http://jsfiddle.net/wao20/Ja54y/19/

First make sure your iframe is loaded, then you can call this to access to your iframe dom.

$('#iframe_id_123').contents().find('#element_inside_your_iframe');

Update:

If you want a pure js solution you can try this:

var f = document.getElementById('f123');
if (f != undefined){
    var doc = f.contentDocument || f.contentWindow.document;
    var txt = doc.getElementById('secret');
    alert(txt.value);
}
else {
    alert('No iframe, no secret!');
}

http://jsfiddle.net/wao20/Ja54y/34/

Du D.
  • 5,062
  • 2
  • 29
  • 34
2

It is possible that the contents of the iframe are not loaded. You can try checking if the iframe is loaded, and if it is, then try to access its document element.

For example, the code to access the document element of the iframe is split into function AfterFrameLoads() which is called during the onload event of the iframe.

var viewfields;  //is a ref to the div with id=123`

if(viewfields) {
    window.alert("viewfields.length=" +  viewfields.length);  //prints len=1 as expected

    // Check if iframe loading is complete, attach rest of code to onload event 
    if (viewfields[0].addEventListener){ // for Mozilla, FF, Chrome, etc...
        viewfields[0].addEventListener("onload",AfterFrameLoads());
    }
    else if (viewfields[0].attachEvent){ // for IE and Opera
        viewfields[0].attachEvent("onload",AfterFrameLoads());
    }
 }

// Attempt to access document after iframe loads.

function AfterFrameLoads(){   
     var innerDoc = viewfields[0].contentDocument || viewfields[0].contentWindow.document;       

     if(innerDoc) {
           window.alert("Wohoo we have an innerDoc");
     }
    else {
      window.alert("no view fields found");
    }
}
KernelPanik
  • 8,169
  • 1
  • 16
  • 14
  • The problem I am having is accessing the inner doc. ie innerDoc is always null - call function to check well after everything is loaded. viewfields is not null - but my problem is getting the contents of the viewfields. – Angus Comber Apr 14 '13 at 11:41
  • Is innerDoc located on the same domain as the page that has the viewfields div/iframe? When I tested this code and tried to point innerDoc to a url that was on a different domain, I got that innerDoc was null (no document object), but that there was a parent window object. – KernelPanik Apr 14 '13 at 13:40
  • The document should be null if the iframe's src is in a different domain, but I'm curious if this is the case. When I tested the source, it worked if the iframe was is in the same domain, but not for an external site like microsoft.com. Ref: http://stackoverflow.com/questions/3999101/html-getting-document-from-iframe – KernelPanik Apr 14 '13 at 13:52
  • In my test the inner doc is a web page from very same web server - it is even a file from same folder. I will create a mockup html and add. – Angus Comber Apr 14 '13 at 15:00
0

var viewfields; //is a ref to the div with id=123`

if(viewfields) { window.alert("viewfields.length=" + viewfields.length); //prints len=1 as expected

// Check if iframe loading is complete, attach rest of code to onload event 
if (viewfields[0].addEventListener){ // for Mozilla, FF, Chrome, etc...
    viewfields[0].addEventListener("onload",AfterFrameLoads());
}
else if (viewfields[0].attachEvent){ // for IE and Opera
    viewfields[0].attachEvent("onload",AfterFrameLoads());
}

}

// Attempt to access document after iframe loads.

function AfterFrameLoads(){
var innerDoc = viewfields[0].contentDocument || viewfields[0].contentWindow.document;

 if(innerDoc) {
       window.alert("Wohoo we have an innerDoc");
 }
else {
  window.alert("no view fields found");
}

}

  • Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you've made – Himanshi Thakur May 05 '21 at 04:50