Reputation: 1828
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 ?
Upvotes: 0
Views: 242
Reputation: 26
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);
}
Upvotes: 1