Search code examples
javascriptphpjqueryhtmlinnerhtml

Run Javascript function after innerHTML from PHP


Im using a xmlhttp.send() to obtain a query result that print a HTML hierarquical list (li ans lu tags) in PHP (jstree_view.php).

After that, I use document.getElementById("treeviewer").innerHTML = this.responseText; to inject the result obtained from PHP to show the information to the user.

I noticed that a javascript function does not work to show a jstree after the code is injected, moreover the jstree function runs before execute innerHTML

The question is, how can solve that issue? Maybe Im not calling the javascript correctly, what is the correct way to call the function? I have tested creating an script element with the javascript function (alert function works fine), also I used eval() as some answers suggested with any good results.

jstree_charge.js

function jstree_charge(tech) {
var index_project_database= document.getElementById("project_select").selectedIndex;
var project_database= document.getElementById("project_select").options[index_project_database].value;

if (tech == "") {
    document.getElementById("treeviewer").innerHTML = "";
    return;
} else {
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById("treeviewer").innerHTML = this.responseText;
            }
    };

    xmlhttp.open("GET","../php/jstree_charge.php?tech=" + tech + "&project=" + project_database, true);
    xmlhttp.send();     
}  }

result of jstree_charge.php This is the result that is injected by innnerHTML in jstree_charge.js

<div name="treeviewer" id="treeviewer">
    <ul>
        <li>RNC5
            <ul>
                <li>00AB2_U
                    <ul>
                        <li>P00AB2A</li>
                        <li>P00AB2B</li>
                        <li>P00AB2C</li>
                        <li>P00AB2D</li>
                        <li>P00AB2E</li>
                    </ul>
                </li>
                <li>00ABC
                    <ul>
                        <li>U00ABCA</li>
                        <li>U00ABCB</li>
                        <li>U00ABCC</li>
                    </ul>
                </li>
           </ul>
        </li>
   </ul>
</div>

jstree_charge.js

    $(document).ready(function(){
    $("#treeviewer").jstree({

        "checkbox" : {
        "keep_selected_style" : false
        },
        "plugins" : [ "checkbox" ]
    });
});

Thanks!


Solution

  • You need to do two things:

    1) Your jsTree function needs to run again after your data is loaded by ajax:

    xmlhttp.onreadystatechange = function() {
       if (this.readyState == 4 && this.status == 200) {
           document.getElementById("treeviewer").innerHTML = this.responseText;
           $("#treeviewer").jstree({
               "checkbox" : {
                   "keep_selected_style" : false
               },
               "plugins" : [ "checkbox" ]
           });
       }
    };
    

    2) You need to change your response slightly. You said the response includes:

    <div name="treeviewer" id="treeviewer">...</div>
    

    However, you already have this element in your page - it's where you are injecting the new response text. The "innerHTML" function replaces content inside the targeted element, not the element itself. Therefore you will end up with a layout like this:

    <div name="treeviewer" id="treeviewer">
      <div name="treeviewer" id="treeviewer">
        <ul>...etc</ul>
      </div>
    </div>
    

    This is invalid HTML - you can't have multiple elements with the same ID. It could potentially cause the jsTree function not to work as expected.

    So you need to remove the "treeviewer" div from the response generated by jstree_charge.php.