0

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!

July
  • 442
  • 4
  • 11
  • two obvious problems: 1) You're injecting a second element with id "treeviewer" inside the existing element with id "treeviewer". IDs must be unique. 2) Assuming the js function you are referring to is the one in jstree_charge.js, that function only runs once when the page is loaded (that's what the document.ready() wrapper round it does). You'd have to run the jstree function again after you've downloaded the new content, otherwise it doesn't know about the new content. – ADyson Feb 15 '17 at 20:15
  • You are right! 1.-the line: document.getElementById("treeviewer").innerHTML = this.responseText; identify the place where it will be injected, this is why Im refering the id tag. so the code is injected correctly in the tag specified. 2.- The script is running after the page is loaded and this is why it doesnt charge the js file. How I run the jstree function after a download the content? – July Feb 15 '17 at 21:12

2 Answers2

1

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.

ADyson
  • 57,178
  • 14
  • 51
  • 63
0

The short answer is: move your jsTree function to run after setting innerHTML so the responseText is ready:

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" ]
           });
       }
};

And the long answer is here: How do I return the response from an asynchronous call?

Community
  • 1
  • 1
dNitro
  • 5,145
  • 2
  • 20
  • 45