admin管理员组

文章数量:1026180

I'm planning to use Bootstrap Treeview where the Json is expected as below. I need to dynamically add element to the "tree" based on respective input nodes

var tree = {};

tree = [
  {
    text: "Parent 1",
    nodes: [
      {
        text: "Child 1",
        nodes: [
          {
            text: "Grandchild 1",
            nodes : [
                {
                    text : "GrandChild 3"
                }
            ]
          },
          {
            text: "Grandchild 2",
            nodes : [
                {
                    text : "GrandChild 4"
                }
            ]
          }
        ]
      },
      {
        text: "Child 2"
      }
    ]
  },
  {
    text: "Parent 2"
  },
  {
    text: "Parent 3"
  },
  {
    text: "Parent 4"
  },
  {
    text: "Parent 5"
  }
];

I've tried array.reduce() but couldn't make that work.

Looking for some approach

I'm planning to use Bootstrap Treeview where the Json is expected as below. I need to dynamically add element to the "tree" based on respective input nodes

var tree = {};

tree = [
  {
    text: "Parent 1",
    nodes: [
      {
        text: "Child 1",
        nodes: [
          {
            text: "Grandchild 1",
            nodes : [
                {
                    text : "GrandChild 3"
                }
            ]
          },
          {
            text: "Grandchild 2",
            nodes : [
                {
                    text : "GrandChild 4"
                }
            ]
          }
        ]
      },
      {
        text: "Child 2"
      }
    ]
  },
  {
    text: "Parent 2"
  },
  {
    text: "Parent 3"
  },
  {
    text: "Parent 4"
  },
  {
    text: "Parent 5"
  }
];

I've tried array.reduce() but couldn't make that work.

Looking for some approach

Share Improve this question edited Apr 23, 2016 at 6:55 ThisMan 2901 silver badge11 bronze badges asked Apr 23, 2016 at 5:32 Ranjan SarkarRanjan Sarkar 612 gold badges2 silver badges5 bronze badges 4
  • 1 Can you describe what you're trying to exactly? Some examples. – ᴇʟᴇvᴀтᴇ Commented Apr 23, 2016 at 5:34
  • I'm geetting some JSON objects from MongoDB, which I need to parse and create JSON object like above, which I can use in Bootstrap treeview. Since the values re ing from Mongo, looking for some dynamic approach – Ranjan Sarkar Commented Apr 23, 2016 at 5:36
  • 1 What you're looking for is called a recursive function. – Jhecht Commented Apr 23, 2016 at 7:26
  • Are you trying to add elements to this? And if so, how? – Jhecht Commented Apr 23, 2016 at 9:01
Add a ment  | 

2 Answers 2

Reset to default 1

Manually, you could do this:

alert(tree[0].nodes[0].nodes[0].nodes[0].text);// alerts "GrandChild 3"
// add a node array:
tree[0].nodes[0].nodes[0].nodes[0].nodes = [{
  text: "GrandChild NEW First"
}];
console.dir(tree);

Shows: Array[5]0: Object nodes: Array[2]0: Object nodes: Array[2]0: Object nodes: Array[1]0: Object nodes: Array[1]0: Object text: "GrandChild NEW First" _proto__: Object length: 1__proto__: Array[0]text: "GrandChild 3" _proto__: Object length: 1

Do same to array 1:

Array[5] 1: Object nodes : Array[1] text : "Parent 2"

tree[1].nodes = [{
  text: "GrandChild NEW Second"
}];

Now you just need code to determine the depth of nodes and what to add (node or text or both) at that point.

EDIT If it makes it clearer, the last addition can also be done thus:

Add a new node array, then push a value into that

tree[1].nodes = [];
tree[1].nodes.push({
  text: "GrandChild NEW Second"
});

Edit 2 Link to Plunkr

Because of the nature of the snippet editor, the code below will not work on the snippet editor, but in order to ensure that the code does not magically vanish from plunkr, I've included it below. All you need to do is include jquery, bootstrap's css file, the treeview css, and treeview js file.

Some Issues

This may just be because I have never used treeview before in my life, but if you have opened up anything on the treeview or selected something, by adding in the new element you erase any of that action. Going through it quickly I didn't see a way to simply rebuild the node list (our tree variable) from the current states. I attempted to pass a pre-defined nodeId to see if we could make the changes directly onto the parent tree variable by using the get[State] mands but the id seems to be generated by the rendering aspect and is not carried over. (to clarify: I gave parent 1 a node id of 1, but when I called a couple of calls on it, I got that it's node id was 0)

The id convention seems to start at the first element (nodeId=0). It first then goes through the children (if any) of that node, incrementing the nodeId as it goes. Theoretically it would be a simple enough script to go back and enumerate the nodeId's manually so that you can make state changes so that the re-render looks the same as before, minus a newly appended node somewhere.

var tree = [{
  text: "Parent 1",
  nodes: [{
    text: "Child 1",
    nodes: [{
      text: "Grandchild 1",
      nodes: [{
        text: "GrandChild 3"
      }]
    }, {
      text: "Grandchild 2",
      nodes: [{
        text: "GrandChild 4"
      }]
    }]
  }, {
    text: "Child 2"
  }]
}, {
  text: "Parent 2"
}, {
  text: "Parent 3"
}, {
  text: "Parent 4"
}, {
  text: "Parent 5"
}];
$(document).ready(function() {
  $('#test').treeview({
    data: tree
  });

  $('button.btn-primary').on('click', function() {
    tree.push({
      text: 'Parent ' + (tree.length + 1)
    });

    $('#test').treeview({
      data: tree
    });

  });
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn./bootstrap/3.3.6/css/bootstrap.css" rel="stylesheet" />
<button class="btn btn-primary">Add Something</button>
<div id="test"></div>

Edit 1

After reading through the OP's question, I'm not 100% that the code below answers what they were looking for. I've asked for further clarification and will keep this answer here until I know more.

Original

I've got some code working on a code pen Here, but I will add it to the snippet editor.

var tree = [{
  text: "Parent 1",
  nodes: [{
    text: "Child 1",
    nodes: [{
      text: "Grandchild 1",
      nodes: [{
        text: "GrandChild 3"
      }]
    }, {
      text: "Grandchild 2",
      nodes: [{
        text: "GrandChild 4"
      }]
    }]
  }, {
    text: "Child 2"
  }]
}, {
  text: "Parent 2"
}, {
  text: "Parent 3"
}, {
  text: "Parent 4"
}, {
  text: "Parent 5"
}];

function recursive_tree(data, tag, child_wrapper, level) {
  var html = [];
  //return html array;
  level = level || 0;
  child_wrapper = (child_wrapper != false) ? child_wrapper : 'ul';
  $.each(data, function(i, obj) {
    var el = $('<' + tag + '>');
    el.html(obj.text);
    if (obj.hasOwnProperty('nodes')) {
      var wrapper = $('<' + child_wrapper + '>');
      var els = recursive_tree(obj.nodes, tag, child_wrapper);
      wrapper.append(els);
      wrapper.appendTo(el);
    }
    html.push(el);
  });
  return html;
}

$(document).ready(function() {
  var html = recursive_tree(tree, 'li', 'ul');
  console.log(html);
  $('#parent').append(html);

});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="parent"></ul>

What you're looking for is something called Recursion, and it's used a lot for things exactly like this. There tends to be a nested/self similar structure.

This should be enough for a basic idea of what to do, from here it's really change the html that gets created. I've never used Bootstrap Treeview, so I have no idea how it is setup HTML wise, otherwise I'd have this be a bit more exact.

I'm planning to use Bootstrap Treeview where the Json is expected as below. I need to dynamically add element to the "tree" based on respective input nodes

var tree = {};

tree = [
  {
    text: "Parent 1",
    nodes: [
      {
        text: "Child 1",
        nodes: [
          {
            text: "Grandchild 1",
            nodes : [
                {
                    text : "GrandChild 3"
                }
            ]
          },
          {
            text: "Grandchild 2",
            nodes : [
                {
                    text : "GrandChild 4"
                }
            ]
          }
        ]
      },
      {
        text: "Child 2"
      }
    ]
  },
  {
    text: "Parent 2"
  },
  {
    text: "Parent 3"
  },
  {
    text: "Parent 4"
  },
  {
    text: "Parent 5"
  }
];

I've tried array.reduce() but couldn't make that work.

Looking for some approach

I'm planning to use Bootstrap Treeview where the Json is expected as below. I need to dynamically add element to the "tree" based on respective input nodes

var tree = {};

tree = [
  {
    text: "Parent 1",
    nodes: [
      {
        text: "Child 1",
        nodes: [
          {
            text: "Grandchild 1",
            nodes : [
                {
                    text : "GrandChild 3"
                }
            ]
          },
          {
            text: "Grandchild 2",
            nodes : [
                {
                    text : "GrandChild 4"
                }
            ]
          }
        ]
      },
      {
        text: "Child 2"
      }
    ]
  },
  {
    text: "Parent 2"
  },
  {
    text: "Parent 3"
  },
  {
    text: "Parent 4"
  },
  {
    text: "Parent 5"
  }
];

I've tried array.reduce() but couldn't make that work.

Looking for some approach

Share Improve this question edited Apr 23, 2016 at 6:55 ThisMan 2901 silver badge11 bronze badges asked Apr 23, 2016 at 5:32 Ranjan SarkarRanjan Sarkar 612 gold badges2 silver badges5 bronze badges 4
  • 1 Can you describe what you're trying to exactly? Some examples. – ᴇʟᴇvᴀтᴇ Commented Apr 23, 2016 at 5:34
  • I'm geetting some JSON objects from MongoDB, which I need to parse and create JSON object like above, which I can use in Bootstrap treeview. Since the values re ing from Mongo, looking for some dynamic approach – Ranjan Sarkar Commented Apr 23, 2016 at 5:36
  • 1 What you're looking for is called a recursive function. – Jhecht Commented Apr 23, 2016 at 7:26
  • Are you trying to add elements to this? And if so, how? – Jhecht Commented Apr 23, 2016 at 9:01
Add a ment  | 

2 Answers 2

Reset to default 1

Manually, you could do this:

alert(tree[0].nodes[0].nodes[0].nodes[0].text);// alerts "GrandChild 3"
// add a node array:
tree[0].nodes[0].nodes[0].nodes[0].nodes = [{
  text: "GrandChild NEW First"
}];
console.dir(tree);

Shows: Array[5]0: Object nodes: Array[2]0: Object nodes: Array[2]0: Object nodes: Array[1]0: Object nodes: Array[1]0: Object text: "GrandChild NEW First" _proto__: Object length: 1__proto__: Array[0]text: "GrandChild 3" _proto__: Object length: 1

Do same to array 1:

Array[5] 1: Object nodes : Array[1] text : "Parent 2"

tree[1].nodes = [{
  text: "GrandChild NEW Second"
}];

Now you just need code to determine the depth of nodes and what to add (node or text or both) at that point.

EDIT If it makes it clearer, the last addition can also be done thus:

Add a new node array, then push a value into that

tree[1].nodes = [];
tree[1].nodes.push({
  text: "GrandChild NEW Second"
});

Edit 2 Link to Plunkr

Because of the nature of the snippet editor, the code below will not work on the snippet editor, but in order to ensure that the code does not magically vanish from plunkr, I've included it below. All you need to do is include jquery, bootstrap's css file, the treeview css, and treeview js file.

Some Issues

This may just be because I have never used treeview before in my life, but if you have opened up anything on the treeview or selected something, by adding in the new element you erase any of that action. Going through it quickly I didn't see a way to simply rebuild the node list (our tree variable) from the current states. I attempted to pass a pre-defined nodeId to see if we could make the changes directly onto the parent tree variable by using the get[State] mands but the id seems to be generated by the rendering aspect and is not carried over. (to clarify: I gave parent 1 a node id of 1, but when I called a couple of calls on it, I got that it's node id was 0)

The id convention seems to start at the first element (nodeId=0). It first then goes through the children (if any) of that node, incrementing the nodeId as it goes. Theoretically it would be a simple enough script to go back and enumerate the nodeId's manually so that you can make state changes so that the re-render looks the same as before, minus a newly appended node somewhere.

var tree = [{
  text: "Parent 1",
  nodes: [{
    text: "Child 1",
    nodes: [{
      text: "Grandchild 1",
      nodes: [{
        text: "GrandChild 3"
      }]
    }, {
      text: "Grandchild 2",
      nodes: [{
        text: "GrandChild 4"
      }]
    }]
  }, {
    text: "Child 2"
  }]
}, {
  text: "Parent 2"
}, {
  text: "Parent 3"
}, {
  text: "Parent 4"
}, {
  text: "Parent 5"
}];
$(document).ready(function() {
  $('#test').treeview({
    data: tree
  });

  $('button.btn-primary').on('click', function() {
    tree.push({
      text: 'Parent ' + (tree.length + 1)
    });

    $('#test').treeview({
      data: tree
    });

  });
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn./bootstrap/3.3.6/css/bootstrap.css" rel="stylesheet" />
<button class="btn btn-primary">Add Something</button>
<div id="test"></div>

Edit 1

After reading through the OP's question, I'm not 100% that the code below answers what they were looking for. I've asked for further clarification and will keep this answer here until I know more.

Original

I've got some code working on a code pen Here, but I will add it to the snippet editor.

var tree = [{
  text: "Parent 1",
  nodes: [{
    text: "Child 1",
    nodes: [{
      text: "Grandchild 1",
      nodes: [{
        text: "GrandChild 3"
      }]
    }, {
      text: "Grandchild 2",
      nodes: [{
        text: "GrandChild 4"
      }]
    }]
  }, {
    text: "Child 2"
  }]
}, {
  text: "Parent 2"
}, {
  text: "Parent 3"
}, {
  text: "Parent 4"
}, {
  text: "Parent 5"
}];

function recursive_tree(data, tag, child_wrapper, level) {
  var html = [];
  //return html array;
  level = level || 0;
  child_wrapper = (child_wrapper != false) ? child_wrapper : 'ul';
  $.each(data, function(i, obj) {
    var el = $('<' + tag + '>');
    el.html(obj.text);
    if (obj.hasOwnProperty('nodes')) {
      var wrapper = $('<' + child_wrapper + '>');
      var els = recursive_tree(obj.nodes, tag, child_wrapper);
      wrapper.append(els);
      wrapper.appendTo(el);
    }
    html.push(el);
  });
  return html;
}

$(document).ready(function() {
  var html = recursive_tree(tree, 'li', 'ul');
  console.log(html);
  $('#parent').append(html);

});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="parent"></ul>

What you're looking for is something called Recursion, and it's used a lot for things exactly like this. There tends to be a nested/self similar structure.

This should be enough for a basic idea of what to do, from here it's really change the html that gets created. I've never used Bootstrap Treeview, so I have no idea how it is setup HTML wise, otherwise I'd have this be a bit more exact.

本文标签: javascriptDynamically create treenested JSON in JSStack Overflow