JS Tree (JStree ) in Bootstrap CSS

Main page Code

<?php
/*
### requirements
1. create a basic js tree with html ul-li tags
2. load with ajax
3. make parent and child check boxes independent of each other
4. load json with ajax
5. check/uncheck all nodes
6. check/uncheck particular node
7. redraw entire tree

*/
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <title>JS Tree in Bootstrap 4 Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

  <!-- JS tree block  -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
  <!-- JS tree block ends here -->

</head>
<body>

<div class="container">
  <h1>JS Tree in Bootstrap Page</h1>
  <p>This is some text.</p>
     <div id="jstree_demo_div">
         <!-- in this example the tree is populated from inline HTML -->

     </div>
     <button onclick="checkAll()" >Check All</button>
     <button onclick="uncheckAll()" >Uncheck All</button>
     <button onclick="check1_2()" >Check 1_2</button>
     <button onclick="uncheck1_2()" >Uncheck 1_2</button>
     <button onclick="getAllChecked()" >Get All Checked</button>
     <button onclick="refreshJSTree()" >Refresh Tree</button>
     <button onclick="reloadJSTree()" >Reload Tree</button>
</div>

  <!-- JS tree block  -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
 <script>
    let  mysJSTree = null;
    let lastExpandedNodeId = "#";
    $( document ).ready(function() {
       console.log( "ready!" );
      loadJSTree();

        mysJSTree.bind("changed.jstree", function (e, data) {

            let currentSelectedNodeIds = []
            data.selected.forEach(function (element, index) {
                currentSelectedNodeIds.push(data.instance.get_node(element).id);
                console.log("pushed " ,index, data.instance.get_node(element).id);
            });//data.selected.forEach(
        });//$.jstree.bind(
    });
    //OR short hand
    //$(function () { $('#jstree_demo_div').jstree(); });
    function loadJSTree()
    {
         //$.jstree.defaults.core.themes.variant = "large";// irrelevant
       mysJSTree = $('#jstree_demo_div').jstree({
                      /* "core" : {
                        "themes" : {
                          "variant" : "large"
                        }
                      }, */
                      'core' : {
                        "dataType" : "json" ,// needed only if you do not supply JSON headers
                        'data' : {
                          //'url' : 'ajax_nodes.html',
                          'url' : function (node) {
                              console.log("node is " + JSON.stringify(node));
                              return "ajax_nodes.html?testVar=testVar"// will be appended with "?id=" + node.id;
                              //return "ajax_nodes.json?testVar=testVar"// will be appended with "?id=" + node.id;
                          },
                          'data' : function (node) {
                              console.log("chosen node.id to expand  is  " + node.id );
                              lastExpandedNodeId = node.id;
                            return { 'id' : node.id };
                          },
                            "success" : function(webChildNodes) {// load complete
                                //console.log("jstree LOAD  COMPLETE arguments ." + JSON.stringify(arguments));
                                console.log("in success " + JSON.stringify(webChildNodes));
                            },
                            complete: function () {// build tree complete, doesnt work for json data loaded
                                console.log("jstree BUILD COMPLETE arguments ." + JSON.stringify(arguments));
                                var childrens = mysJSTree.jstree("get_children_dom",lastExpandedNodeId);

                                /* get child nodes loaded with html ul-li tags*/
                                    console.log("Child Nodes of " + lastExpandedNodeId);
                                   for(var i=0;i<childrens.length;i++)
                                   {
                                        console.log(childrens[i].id + " : " + childrens[i].innerText);
                                   }
                                   /* get child nodes loaded with html ul-li tags ends here*/

                                   /* get child nodes loaded with JSON*/
                                   /*
                                {"0":{"readyState":4,
                                        "responseText":"[{\"id\":\"upkarTopicNode1\",\"text\":\"root\",\"topic_id\":1,\"children\":true}]",
                                        "responseJSON":[{"id":"upkarTopicNode1","text":"root","topic_id":1,"children":true}],
                                        "status":200,
                                        "statusText":"OK"
                                      },
                                  "1":"success"}
                                */
                               /* let responseJSON = arguments[0].responseJSON;
                               responseJSON.forEach(function(responseJSONItem,itemIndex){
                                                                 if(responseJSONItem.topic_id == 2)
                                                                 {
                                                                     //let liId = arguments[0].responseJSON.id;
                                                                     //document.getElementById(liId).addClass("stree-unchecked");
                                                                     responseJSON[itemIndex].state = { "checkbox_disabled" : true };
                                                                 }//if(arguments[0].responseJSON.topic_id == 2)
                                                             });   */

                                   /* get child nodes loaded with JSON ends here*/

                            }//complete: function () {/
                        }//'data' : {
                      },//'core' : {
                      "checkbox" : {
                        "keep_selected_style" : false, 
                        "three_state" : false //otherwise parent and child cannot be checked inedpendently https://www.jstree.com/api/#/?q=$.jstree.defaults.checkbox&f=$.jstree.defaults.checkbox.three_state
                      },
                      //https://www.jstree.com/plugins/
                      "plugins" : ["checkbox" ]// "wholerow"/*w/o dotted lines*/, 
                    });//mysJSTree = $('#jstree_demo_div').jstree({
    }//function loadJSTree()

    function check1_2()
    {
        mysJSTree.jstree().check_node("j1_2");
    }//function check1_2()()
    function uncheck1_2()
    {
        mysJSTree.jstree().uncheck_node("j1_2");
    }//function check1_2()()
    function checkAll()
    {
        mysJSTree.jstree().select_all(true);
    }//function checkAll()

    function uncheckAll()
    {
        mysJSTree.jstree().deselect_all(true);
    }//function uncheckAll()
    function getAllChecked()
    {
        //https://www.jstree.com/api/#/?q=checkbox&f=get_checked([full])
        let checkedNodes = mysJSTree.jstree().get_checked();
        console.log(checkedNodes);
    }//function getAllChecked()
    function refreshJSTree()
    {
        mysJSTree.jstree("refresh");//https://stackoverflow.com/a/3682176
    }//function refreshJSTree()
    function reloadJSTree()
    {
        mysJSTree.jstree("destroy");
        loadJSTree();
    }//function reloadJSTree()
 </script>

  <!-- JS tree block  ends here -->
</body>

ajax_nodes.html

<ul>
<li class="jstree-closed">Node 1</li>
<li class="jstree-closed">Node 2</li>
</ul>

ajax_nodes.json

[{ "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },{ "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },{ "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },{ "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }]

Interepreted as

[
       { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
       { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },
       { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
       { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
    ]

When Child nodes are to be dynamically loaded

[{"id":"upkarTopicNode1","text":"Test Node 1","topic_id":73,"children":true},{"id":"upkarTopicNode2","text":"Android App Development","topic_id":120,"children":false},{"id":"upkarTopicNode3","text":"Company Registration","topic_id":86,"children":false},{"id":"upkarTopicNode4","text":"Competitor apps","topic_id":51,"children":true},{"id":"upkarTopicNode5","text":"Distorted History ","topic_id":122,"children":false},{"id":"upkarTopicNode6","text":"DrugsAndCosmeticsAct","topic_id":239,"children":false},{"id":"upkarTopicNode7","text":"Essential s/w","topic_id":52,"children":true},{"id":"upkarTopicNode8","text":"Evidence","topic_id":148,"children":false},{"id":"upkarTopicNode9","text":"Legal","topic_id":45,"children":true},{"id":"upkarTopicNode10","text":"Bussiness","topic_id":25,"children":true},{"id":"upkarTopicNode11","text":"Top Up","topic_id":82,"children":false},{"id":"upkarTopicNode12","text":"LegalLive","topic_id":33,"children":true},{"id":"upkarTopicNode13","text":"MAPC","topic_id":37,"children":true},{"id":"upkarTopicNode14","text":"Motivational","topic_id":129,"children":false},{"id":"upkarTopicNode15","text":"MyProjects","topic_id":336,"children":false},{"id":"upkarTopicNode16","text":"New Tchnologies","topic_id":123,"children":false},{"id":"upkarTopicNode17","text":"Office Management","topic_id":41,"children":false},{"id":"upkarTopicNode18","text":"Opportunities","topic_id":127,"children":false},{"id":"upkarTopicNode19","text":"OSOL Solutions","topic_id":429,"children":false},{"id":"upkarTopicNode20","text":"Patent4DSL2UML2Code","topic_id":43,"children":false},{"id":"upkarTopicNode21","text":"Peacefulls","topic_id":31,"children":true},{"id":"upkarTopicNode22","text":"Personal","topic_id":67,"children":false},{"id":"upkarTopicNode23","text":"Project Management","topic_id":40,"children":true},{"id":"upkarTopicNode24","text":"Propoganda","topic_id":24,"children":false},{"id":"upkarTopicNode25","text":"Software License","topic_id":44,"children":false},{"id":"upkarTopicNode26","text":"Startups","topic_id":121,"children":false},{"id":"upkarTopicNode27","text":"SW devp","topic_id":55,"children":true},{"id":"upkarTopicNode28","text":"Time Management","topic_id":98,"children":false},{"id":"upkarTopicNode29","text":"Vlogging","topic_id":58,"children":true},{"id":"upkarTopicNode30","text":"webRoot","topic_id":19,"children":true},{"id":"upkarTopicNode31","text":"webRoot2","topic_id":20,"children":false}]

Interpreted as

[
{"id":"upkarTopicNode1","text":"Test Node 1","topic_id":73,"children":true},
{"id":"upkarTopicNode2","text":"Android App Development","topic_id":120,"children":false},
{"id":"upkarTopicNode3","text":"Company Registration","topic_id":86,"children":false},
{"id":"upkarTopicNode4","text":"Competitor apps","topic_id":51,"children":true},
{"id":"upkarTopicNode5","text":"Distorted History ","topic_id":122,"children":false},
{"id":"upkarTopicNode6","text":"DrugsAndCosmeticsAct","topic_id":239,"children":false},
{"id":"upkarTopicNode7","text":"Essential s/w","topic_id":52,"children":true},
{"id":"upkarTopicNode8","text":"Evidence","topic_id":148,"children":false},
{"id":"upkarTopicNode9","text":"Legal","topic_id":45,"children":true},
{"id":"upkarTopicNode10","text":"Bussiness","topic_id":25,"children":true},
{"id":"upkarTopicNode11","text":"Top Up","topic_id":82,"children":false},
{"id":"upkarTopicNode12","text":"LegalLive","topic_id":33,"children":true},
{"id":"upkarTopicNode13","text":"MAPC","topic_id":37,"children":true},
{"id":"upkarTopicNode14","text":"Motivational","topic_id":129,"children":false},
{"id":"upkarTopicNode15","text":"MyProjects","topic_id":336,"children":false},
{"id":"upkarTopicNode16","text":"New Tchnologies","topic_id":123,"children":false},
{"id":"upkarTopicNode17","text":"Office Management","topic_id":41,"children":false},
{"id":"upkarTopicNode18","text":"Opportunities","topic_id":127,"children":false},
{"id":"upkarTopicNode19","text":"OSOL Solutions","topic_id":429,"children":false},
{"id":"upkarTopicNode20","text":"Patent4DSL2UML2Code","topic_id":43,"children":false},
{"id":"upkarTopicNode21","text":"Peacefulls","topic_id":31,"children":true},
{"id":"upkarTopicNode22","text":"Personal","topic_id":67,"children":false},
{"id":"upkarTopicNode23","text":"Project Management","topic_id":40,"children":true},
{"id":"upkarTopicNode24","text":"Propoganda","topic_id":24,"children":false},
{"id":"upkarTopicNode25","text":"Software License","topic_id":44,"children":false},
{"id":"upkarTopicNode26","text":"Startups","topic_id":121,"children":false},
{"id":"upkarTopicNode27","text":"SW devp","topic_id":55,"children":true},
{"id":"upkarTopicNode28","text":"Time Management","topic_id":98,"children":false},
{"id":"upkarTopicNode29","text":"Vlogging","topic_id":58,"children":true},
{"id":"upkarTopicNode30","text":"webRoot","topic_id":19,"children":true},
{"id":"upkarTopicNode31","text":"webRoot2","topic_id":20,"children":false}]