1

I am trying to display a tree structure in my web project.

I am using Symfony 3.4.x with jsTree v3.3.5.

PROBLEM

I can not get the tree to display when using json and ajax.

I am using an example from official jstree documentation.

If i hard code data in json format the tree is displayed without a hitch, but when i return the same json as part of ajax call - tree is not displayed (i get only one item, displayed as a folder, without a name).

I want to display all the tree nodes fully open - so loading all items is required.

CODE

my data in json format (i am using alternative json notation as per jstree documentation)

{"success":true,
"data":[
    {"id":"50","parent":"#","text":"test_root"},
    {"id":"51","parent":"50","text":"test_1"},
    {"id":"123","parent":"51","text":"test_2"},
    {"id":"73","parent":"51","text":"test_3"},
    {"id":"75","parent":"51","text":"test_4"},
    {"id":"76","parent":"51","text":"test_5"},
    {"id":"74","parent":"51","text":"test_6"},
    {"id":"78","parent":"51","text":"test_7"},
    {"id":"124","parent":"51","text":"test_8"},
    {"id":"77","parent":"50","text":"test_9"}
]}

using jstree

$(document).ready(function()
{
    let project_tree;
    project_tree = $('#file-tree-json');

    project_tree.jstree({
        'core':
        {
            'data':
            {
                'url': '/tree/prepare',
                'dataType': 'json',
                'data': function (node) {
                    console.log(node);
                    return { 'id': node.id };
                },
            }
        },
        "types": {
            "root": {
                "icon": "lnr lnr-home"
            },
            "folder": {
                "icon": "lnr lnr-folder"
            },
            "file": {
                "icon": "lnr lnr-file-empty"
            }
        },
        "search": {
            show_only_matches: true,
            search_callback: function (str, node)
            {
                if (node.text.toLowerCase().indexOf(str) >= 0) { return true; }
                }
        },
        "plugins": [ "types", "search" ]
    });
}

code in my controller that prepares tree items data in json format

$em = $this->getDoctrine()->getManager();
$repo_file_tree = $em->getRepository('App:FileTree');

try
{
    $build_my_tree_json = $repo_file_tree->prepareJsonTree($build_my_tree);

    return new JsonResponse([
        'success' => true,
        'data'    => $build_my_tree_json
    ]);
}
catch (\Exception $exception)
{
    return new JsonResponse([
        'success' => false,
        'code'    => $exception->getCode(),
        'message' => $exception->getMessage(),
    ]);
}

Other discussions on SO that are related and which i already read, but in my opinion, they did not solve the problem at hand or/and refer to jstree version that is out of date

  1. jsTree unable to load root nodes from AJAX call
  2. jsTree - loading subnodes via ajax on demand
  3. JSTree - Load nodes dynamically
  4. JStree and ajax
  5. https://stackoverflow.com/a/22965656

CONCLUSION

What am i doing wrong?

Maybe i am overlooking some detail or technicality?

Thank you for your comments and answers.

UPDATE 1

when i am returning only data

return new JsonResponse([
    $build_my_tree_json
]);

i get additional "[]" as so

[[
    {"id":"50","parent":"#","text":"test_root"},
    {"id":"51","parent":"50","text":"test_1"},
    {"id":"123","parent":"51","text":"test_2"},
    {"id":"73","parent":"51","text":"test_3"},
    {"id":"75","parent":"51","text":"test_4"},
    {"id":"76","parent":"51","text":"test_5"},
    {"id":"74","parent":"51","text":"test_6"},
    {"id":"78","parent":"51","text":"test_7"},
    {"id":"124","parent":"51","text":"test_8"},
    {"id":"77","parent":"50","text":"test_9"}
]]

How can one remove extra "[]" from json or reference inner array?

UPDATE 2

it works when there are returned only data about tree nodes in json format.

working example

return new JsonResponse($build_my_tree_json);

So how to make jstree work with additional data in ajax response?

There should be a way to extract all the data about tree from response that contains status and data (response as displayed in my questions CODE section).

Rikijs
  • 728
  • 1
  • 12
  • 48
  • 1
    try this -> return new JsonResponse( $build_my_tree_json ); instead of this return new JsonResponse( [$build_my_tree_json] ); – episch Sep 17 '18 at 18:46
  • Thank you @episch, you noticed what i was overlooking. Removing array from response fixed the problem. – Rikijs Sep 18 '18 at 15:09

1 Answers1

0

The structure of your JSON response doesn't work well with jsTree. jsTree expects an Array of nodes. Your output structure has an array inside the data object. You should have a structure as below in your response for it to work.

 [
        {
            "id": "50",
            "parent": "#",
            "text": "test_root",
            "opened":true
        },
        {
            "id": "51",
            "parent": "50",
            "text": "test_1"
        },
        {
            "id": "123",
            "parent": "51",
            "text": "test_2"
        },
        ...
        ...
]
Stephen S
  • 3,936
  • 2
  • 23
  • 33
  • Thank you for your comment. Could you provide a code example displaying how to use `tree data` that are under `data` key in returned json? I can not seem to find the right way... – Rikijs Sep 17 '18 at 15:06
  • Like @episch says in a comment above, you should try return new JsonResponse( $build_my_tree_json); I haven't used Symfony so I am just guessing here.. – Stephen S Sep 18 '18 at 06:19
  • Thank you, @Stephen it worked. No more additional array in json response. – Rikijs Sep 18 '18 at 15:08