1

I created a diagram of a tree in jstree. Because I have a lot of nodes data I want the load to be lazy. How is it possible that with every click on a parent there will be a call to mysql database and the children's will be retrieved?

Like this idea: How to only display a TreeView expand sign [+] if children exist

Thank you!

semicolon
  • 255
  • 1
  • 3
  • 11
  • Do this [jstree demo](https://www.jstree.com/demo/) is of any help? – Wazeed Apr 19 '21 at 06:06
  • No thanks, But in their example there is a file that contains all the data and from it makes a lazy upload. I want every click of a parent to retrieve an SQL query. Would appreciate help! – semicolon Apr 19 '21 at 06:12
  • It is actually doing an ajax call to retrieve that file. In your implementation, you should replace the logic of that ajax to fetch details based on data from SQL. The query includes `?id=demo_root_1` the id of the clicked node. – Wazeed Apr 19 '21 at 06:21
  • Yes, But where do I add the queries? It is not possible within "DATA" to perform asynchronous readings. – semicolon Apr 19 '21 at 06:27
  • You would need to create an endpoint in your ajax API which handles the queries and returns children data in the required format for jstree – Wazeed Apr 19 '21 at 06:43
  • Ok, But where is the submission operation for the API? – semicolon Apr 19 '21 at 07:36
  • This one will be taken care of by jstree. Just need to configure while initializing with [core.data](https://www.jstree.com/api/#/?f=$.jstree.defaults.core.data), `url` to hit, and the `data` query to be sent based on node. – Wazeed Apr 19 '21 at 07:42
  • In URL should I give the URL of the API? And how can I send the ID per parameter in the URL to each node? – semicolon Apr 19 '21 at 07:46

1 Answers1

2
$('#tree').jstree({
    'core': {
        'data': {
            // This is the API URL for processing child nodes
            'url': '/get/children/',
            // This method is used to to prepare query data
            'data': function (node) {
                // This will add a query `?id=node_id_value`
                // Add your own query data as per the requirement of API endpoint for processing
                return { 'id': node.id };
            }
        }
    }
});

The url property is to mention the URL to contact for children nodes, and the data function which runs over a clicked tree node to prepare query data to pass with URL.

Below are demo API endpoints from JSTREE for lazy loading

Root Node

API endpoint: https://www.jstree.com/fiddle/?lazy&id=%23

[
    {
        "id": 1,
        "text": "Root node",
        // Children of root node
        "children": [
            {
                "id": 2,
                "text": "Child node 1",
                "children": true // Child node 1 still has to be loaded lazily
            },
            {
                "id": 3,
                "text": "Child node 2"
            }
        ]
    }
]

Child node 1

API endpoint: https://www.jstree.com/fiddle/?lazy&id=2

This will load the children node details, as the id 2 is of Child node 1

Notes:

  • Node without children property is considered as the final node in the tree branch.
  • children property of a node is either an array of nodes to render child nodes immediately or, a boolean true for loading children lazily.
  • Each node must have an id which is to be unique per node, so that the node id could be used at API endpoint for processing respective child nodes.

Added a sample snippet to identify whether the selected node has children or not with event changed.jstree

$(function () {
    $('#lazy').jstree({
        'core': {
            'data': {
                "url": "//www.jstree.com/fiddle/?lazy",
                "data": function (node) {
                    return { "id": node.id, "noCache": Date.now() };
                }
            }
        }
    });

    $('#lazy').on('changed.jstree', function (e, data) {
        if (data.selected.length) {
            var selected = data.instance.get_node(data.selected[0]);
            var hasChildren = !selected.state.loaded || selected.children.length > 0;
            console.log(`Selected = ${selected.text}, hasChildren = ${hasChildren}`);
        }
    })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.11/jstree.min.js" integrity="sha512-bU6dl4fd2XN3Do3aWypPP2DcKywDyR3YlyszV+rOw9OpglrGyBs6TyTsbglf9umgE+sy+dKm1UHhi07Lv+Vtfg==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.11/themes/default/style.min.css" integrity="sha512-P8BwDSUInKMA7I116Z1RFg/Dfk85uFdliEUYO7vQlwtxLVMNvZimfMAQsaf++9EhlAGOVX6yhDQAIY3/70jDUg==" crossorigin="anonymous" />


<div id="lazy" class="demo"></div>

Hope that this information helps.

Wazeed
  • 1,230
  • 1
  • 8
  • 9
  • Ok, Thank you very much!! You helped me a lot! I'm trying it ... – semicolon Apr 19 '21 at 07:53
  • Hi, How do I know if the node is a parent or a child? I set a variable named children that contains true or false but JSTREE does not refer to it. – semicolon Apr 19 '21 at 12:16
  • `{ children: true }` this means to jstree that, the current node still has children nodes to be loaded through lazy loading. And when you click on this node, there would be an ajax request to API endpoint with node id. – Wazeed Apr 19 '21 at 13:57
  • I have updated the answer to explain in little detail about JSTREE node format, and also added a code snippet to identify whether the selected node has child nodes or not. Hope this information helps. – Wazeed Apr 19 '21 at 15:05
  • Thank you so much it works for me! I've got no words!!! – semicolon Apr 19 '21 at 15:13