Javascript tree structure not working properly

Hi,

Let me explain the scenario. I have a main html (e.g. main.html) page, which includes
a link to inner.html page. Clicking this link will load the inner page, containing a tree

structure.

http://www.jayakumar.net/sample/main.html

The loading method is such that only the body content from inner page is loaded to the main

page, without refreshing the main page.I believe this method is called partial rendering of pages.

The method used to load is:

A hidden iframe and a div (the hidden iframe is used to fetch other html content and to

write it to the div).

<div id=‘bodyContent’ style=“display:none;”></div> (This is the div into which the content

is written)
<iframe id=‘process’ name=‘process’ style=‘visibility: hidden; height:0px’

onload=‘javascript:loadResults();’></iframe> (This iframe reads data and writes to the

div)

The onload event of iframe calls the following function

<script type=“text/javascript”>
function loadResults() {

    var processElm = document.getElementById('process');
    var bodyContentElm = document.getElementById('bodyContent');
           
    //eval of script content;
   
    bodyContentElm.innerHTML = processElm.contentWindow.document.body.innerHTML;
    bodyContentElm.style.display = "block";
}

</script>

I added the tree structure to the inner.html page. In this case I had to include both the

css and js files for tree stucture, in the <head> section of parent page (i.e main.html).

But when I run the main.html page, the tree structure is not working. Only the text is

displayed. In firefox, refreshing the page will load the tree. But not in other browsers.Even if the tree is displayed correctly first time, clicking the link again will not load the tree.

Please note that due to some technical reasons, I cannot change the iframe method. And also

I am a designer and have a very little programming knowledge. Can any body help me.Not only this tree, but other UI controls like Adobe spry, other third party scripts etc fail to render correctly in such a situation.

Regards,
JK

folder-tree-static.js:286
Uncaught TypeError: Cannot call method ‘getElementsByTagName’ of null

Being a non-programmer it would be easier for me if you could point out the changes to be done.

I’m afraid that I have little experience with Adobe.spry types of situations, so I wish you well with the issue.

Hi,

OK, no problem. Let me try. But one thing to note is that what ever scripts we use, if we give it in the head section of inner.html and access that page directly, things are working fine. But when accessed through the main.html page, controls fail to execute properly. I believe that this is due the method used for writing content to div.

Any way thanks for the reply.

Ok, it looks like I got it. There were two main problems with the code you had.

1. initTree was firing too early

At the bottom of folder-tree-static.js, you have this line:

window.onload = initTree;

But we don’t want initTree to execute when the window is loaded; we want it to execute when the “Inner” page is loaded into the iframe. So take that line out, and add this line to the end of your loadResults function:

initTree();

2. The iframe’s onload event was firing immediately

The iframe’s onload event fires when the user clicks on the “Inner” link, but it also fires when the iframe element itself is first created. That means that, as soon as the empty iframe element (with an empty src attribute) is created by the browser, it executes the loadResults function. But loadResults assumes that content has been opened in the iframe. So you need to add this check to the function:


//eval of script content;
if (processElm.contentWindow.document.body.innerHTML) {
    bodyContentElm.innerHTML = processElm.contentWindow.document.body.innerHTML;
    bodyContentElm.style.display = "block";
    initTree();
}

I made these two changes, and it looks like it works.

Hi sdleihssirhc,

Will check the code tomorrow at office and let you know. Thanks for your effort.

Hi,

Great!!! Now the tree works fine. Thank you.

One more help appreciated. Please visit http://www.jayakumar.net/test/main.html

Select the “Inner page” link under Modules drop down. You will get an Adobe Spry tab. Here we have the same problem. The tab doesn’t work. If you could kindly suggest the changes to be done to make it work, it would be great.

Regards
JK

It looks like I might have this one figured out, too. I think the whole thing works like this:

The tabbed stuff, including the JavaScript that initiates the tabbed stuff, is located on inner.html. When the user is on main.html, and clicks the “Inner” link, the page loads it by copying the innerHTML property from the iframe into a div.

The problem with this is that script tags, copied via innerHTML, do not execute again in their new location. So you copied this…


  <script type="text/javascript"> 
<!--
var TabbedPanels1 = new Spry.Widget.TabbedPanels("TabbedPanels1");
//-->
  </script> 

…but it didn’t do anything. The solution, as in the first problem, is to move this line into the loadResults function. One potential problem, however, is that if the user ever actually goes to inner.html, this JavaScript line won’t be there, and so the tabbed menu will be broken.

Hi,

Thanks again. Working fine. If the inner page is accessed directly, we include the .js file in the head portion of inner page. The script works fine. But in my case the user is not going to access the page directly. So no problem.

Can you tell me one thing. In your example what happens if we do not use the if condition, and put the script directly? (ref. previous example)

//eval of script content;
if (processElm.contentWindow.document.body.innerHTML) {
bodyContentElm.innerHTML = processElm.contentWindow.document.body.innerHTML;
bodyContentElm.style.display = “block”;
initTree();
}

I mean whether this ‘if’ condition is necessary?.. just a doubt…

I don’t have those files anymore, but after looking at the initTree function, I think that “if” is necessary. The “for” loop starts with these two lines:


var dhtmlgoodies_tree = document.getElementById(idOfFolderTrees[treeCounter]);
var menuItems = dhtmlgoodies_tree.getElementsByTagName('LI');	// Get an array of all menu items

“idOfFolderTrees[treeCounter]” will return the string “dhtmlgoodies_tree2.” So it will try to get the element with that id. But if that element hasn’t been loaded yet, it will just return the null object. And because you can’t “getElementsByTagName(‘LI’)” from the null object, it should throw an error and abort the script.

I think.

Hi sdleihssirhc,

Thanks for your great help. Have noted your suggestions. Now things are working fine.

Regards,
JK