0

I am using angular and want to show a nested tree of folder like this in html :

<div id="tree">
    <ul>
        <li ng-repeat='folder in folderList' ng-include="'/templates/tree-renderer.html'"  id="{{ folder.htmlId }}">
        </li>
    </ul>
</div>

And in the tree-renderer.html I have :

<a href='/#/folders{{ folder.link.href }}'>
    <span>{{folder.name}} 
        <small>{{ folder.nbDocIn }}
        </small>
    </span>
</a>
<ul>
    <li ng-repeat="folder in folder.children" ng-include="'/templates/tree-renderer.html'">
    </li>
</ul>

Since I get the result thanks to a Rest request which need to be done each time I modify something, I want the my following code to be fast.

I receive from the Rest request a json like this :

        {
            "key": "folder1"
        },
        {
            "key": "folder2"
        },
        {
            "key": "folder1/subFolder1"
        },
        {
            "key": "folder2/subFolder2"
        },
        {
            "key": "folder1/subFolder2"
        },
        {
            "key": "folder2/subFolder2/subSubFolder2"
        }

Not that the list is not necessary ordered. As you have seen in the html, I now need to transform this list to this one :

        {
            "key": "folder1",
             "children": [{
                    "key": "folder1/subFolder1"
              }, {
                    "key": "folder1/subFolder2"
              }]
        },{
            "key": "folder2",
             "children": [{
                    "key": "folder2/subFolder1",
                    "children": [{
                         "key": "folder2/subFolder1/subSubFolder2"
                    }]
              }]
        }

For now I need two recursive function to make it possible, one to create arrays of childrens and one to put those arrays into an attribute children

I would like to make just one, have you some ideas of how to make it ?

1 Answer 1

1

Basicly, it is better to make a structured list from server-side than client-side.

But in your case, you need to identify fathers (folders) for each element and place them in the correct item. So you don't need recursive.

A functionnaly code : (2 functions : structuring and rendering)

var list = [{
        key: 'folder1'
    },{
        key: 'folder2'
    },{
        key: "folder1/subFolder1"
    },{
        key: "folder2/subFolder2"
    },{
        key: "folder1/subFolder3"
    },{
        key: "folder2/subFolder2/subSubFolder2"
    }];
    $('body').ready(function(){
        ord_list = construct_ord_list(list);
        construct_html(ord_list);
    });
    var construct_ord_list = function(list){
        var finished = false;
        var running = true;
    // Construct a list with a father property for each items
        var res = [];
        for(i in list)
            res.push({  key: list[i].key,   father: ''});
    // Identifying fathers
        while (!finished){
            if (!running)
                finished = true;
            running = false;
            for(i in res)
                if(res[i].key.indexOf('/') > -1){
                    running = true;
    // father recepts the left side of key value from '/'
                    res[i].father = res[i].key.substring(0,res[i].key.indexOf('/'));
    // key recepts the right side of key value from '/'
                    res[i].key = res[i].key.substring(res[i].key.indexOf('/')+1,res[i].key.length);
                }
        }
        return res;
    }
    var construct_html = function(list){
        var text = '<ul>';
        for(i in list)
            if(list[i].father == '')
                text += '<li id="item_'+list[i].key+'">'+list[i].key+'<ul class="children"></ul></li>';
        $('body').append(text+'</ul>');
        for(i in list)
            if(list[i].father != '')
                $('#item_'+list[i].father).find('.children').first().append('<li id="item_'+list[i].key+'">'+list[i].key+'<ul class="children"></ul></li>');
    }

Obviously JQuery is not necessary but allows a more readable code...

If you really want to have a tree structured by javascript, those two functions will help you : (just one recursive)

    var construct_tree = function(list){
        var res = [];
        for(i in list)
            if(list[i].father == '')
                res.push({  key: list[i].key,   children:   []});
        for(i in list)
            if(list[i].father != '')
                insert_child(res,list[i]);
        return res;
    }
    var insert_child = function(list,elmt){
        for(i in list)
            if (list[i].key == elmt.father)
                list[i].children.push({ key: list[i].key,   children:   []});
            else if (list[i].children.length > 0)
                insert_child(list[i].children,elmt);
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, with a few edit for the "has a father" condition, it is exactly what I needed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.