0

So I've been stuck on this for a bit...
I have an HTML page with a div element and an inline frame (iframe):

<!DOCTYPE html>
<head><meta charset="UTF-8"><link rel="stylesheet" type="text/css" href="/GLS_DBSearchProject/resources/css/GLS_DBSearchMainStyle.css"></head>

<div id="DebugOutput">DEBUG-OUTPUT</div>
<body align="center">
    <div class="PWContainer"><iframe class="ProgramWindow" src="index.php"></iframe></div> 
</body>


<?php

The div is simply there as a box that I made for testing as I get comfortable with JavaScript. The iframe houses a separate .php page "index.php". The HTML for "index.php" is entirely generated by the functions in this php code:

class UserInterface {
var $ParentAppInstance;

function __construct($AppInstance){
    $this->ParentAppInstance = $AppInstance;
    $this->DrawPageHTML();
    $this->DrawDBSetDropdown();
    $this->DrawAdvancedSearchBar();
}

//Override this function to change the HTML and PHP of the UI page.
protected function DrawPageHTML(){

    echo '
    <!----Header-HTML--------------------->
    <div align="center">
      <table width="980" height="207" border="0">
        <tr>
          <td width="411"><img src="resources/logo.png" alt="" width="491" height="145" align="middle" /></td>
          <td width="411"><img src="resources/Logo2.png" width="462" height="171" alt="Logo" /></td>
        </tr>
      </table>
    </div>
    <!------------------------------------>



    <body>
        <script src=/GLS_DBSearchProject/JavaScript/UserInterface.js>
        </script>
    </body>




    ';

    echo '$AppInstanceData: ' . '<br>';
    echo '--CurrentDBSet_Str: ' . $this->ParentAppInstance->CurrentDBSet_Str;
}

protected function DrawDBSetDropdown(){
    echo '<div align="right">';
        echo '<select onchange="SwitchDatabaseSet(this.ownerDocument)" name="DBSetList" form="DBSetSelector">';
        $i = 0;
        foreach ($this->ParentAppInstance->DBSets_Arr as $DBSet){
            if($DBSet->DBSetName == 'DBSet0'){/* DO NOTHING. IE. IGNORE IT*/}
            else{
                $i++;
                echo '<option value="' . $DBSet->DBSetName . '">' . $DBSet->DBSetName . '</option>';
            }
        }
        echo '</select>';
    echo '</div>';

}

In the DrawDBSetDropdown() function of the UserInterface class, I am drawing a selection box with variable options. Whenever the user changes the state of this selector, I'm calling the SwitchDatabaseSet() javascript function with the HTML DOM object of "index.php".

Up to this point, everything seems to work fine. Here's where things get weird:

function JSTEST(){
window.alert("JS Called Successfully!!");
}

function SwitchDatabaseSet(MainPageDoc){
    window.alert(null === MainPageDoc);//1. 
    window.alert(MainPageDoc.domain);//2. 
    MainPageDoc.getElementById("DebugOutput").innerHTML = "Test";//3.
 }
  1. Result: false. MainPageDoc is not null.
  2. Result: localhost. As expected the page is running on localhost. Notably, MainPageDoc != null.
  3. Suddenly MainPageDoc supposedly equals null; as I get the following Error:

Uncaught TypeError: Cannot set property 'innerHTML' of null

*document.getElementById() produces an identical result.

I'm trying to change the text of the DebugOutput <div>, but it's not working because of the issue above.
In 1. and 2. both indicate that MainPageDoc isn't null, so why am I getting the error at 3. ? What am I doing wrong here?

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Brandon S.
  • 306
  • 1
  • 4
  • 14
  • 2
    `Uncaught TypeError: Cannot set property 'innerHTML' of null` does not tell you that `MainPageDoc` is `null` but that there is no element with the id `DebugOutput` in the DOM at the time when you call `getElementById("DebugOutput")`. `getElementById` returns `null` if it does not find the requested element. If `MainPageDoc` would be `null` then the error would be `Uncaught TypeError: Cannot read property 'getElementById' of null`. – t.niese Feb 24 '16 at 19:38
  • @t.niese thanks. That makes sense. But I can't seem to figure out why it won't detect my div. Even when I use document.getElementById(). "document" should reference the HTML document that the script is declared within.. (which in this case is the HTML document... figured it out. Thanks – Brandon S. Feb 24 '16 at 19:44

1 Answers1

1

I don't think this is actually possible to do, and I may be wrong, but here is why: It is possible, see second edit.

index.php generates an html webpage (let's call that "index_html")

The <script src="UserInterface.js"></script> tag to implement UserInterface.js is implemented within "index_html".

Therefore: document.getElementById("DebugOutput") and MainPageDoc.getElementByID("DebugOutput") are effectively identical, and they return null because they are both looking for an element with id="DebugOutput".

This <div> is implemented in the first bit of HTML code that I provided <call that "true_index.html">, and not index_html. Therefore, both statements return null as described here.

Edit: I don't think it is possible to edit an HTML element in a parent HTML document from JavaScript that is contained within an iframe. I'll report back after I dig into this some.

Edit: This pretty much sums up the issue, was easy to find once I knew what I was looking for.

Community
  • 1
  • 1
Brandon S.
  • 306
  • 1
  • 4
  • 14