I have a tree data like this:
var tree = [
{
id:"11",
text: "Parent 1",
type:"Parent",
nodeSelected:false,
nodes: [
{
text: "Child 1",
parentId: "11",
id:"21",
nodeSelected:false,
type: "Child",
nodes: [
{
id:"36",
text: "Grandchild 1",
parentId: "21",
nodeSelected:false,
nodes:[],
type: "Grandchild"
},
{
id:"38",
text: "Grandchild 2",
parentId: "21",
nodes:[],
nodeSelected:false,
type: "Grandchild"
}
]
},
{
id:"43",
text: "Child 2",
nodeSelected:false,
parentId:"11",
type: "Child",
nodes: [
{
id:"52",
parentId:"43",
text: "Grandchild 1 of child 2",
nodeSelected:false,
nodes:[],
type: "Grandchild"
}
]
}
]
},
{
id:"46",
text: "Parent 2",
nodeSelected:false,
type: "Parent",
nodes:[]
},
{
id:"48",
text: "Parent 3",
nodeSelected:false,
type: "Parent",
node: [
{
id:"70",
text: "child 3",
parentId: "48",
type: "Child",
nodeSelected:false,
nodes:[]
}
]
}
];
All of the nodeSelected
are false.
I have group of Ids in form of an array.
groupedIds=["11","21","43","52","48"];
I want to do nodeSelected
property true based on groupId array
with some condition.
the condition is such that if a parentId is mentioned along with its children ids then nodeSelected
property of parent should remain false and child's nodeSelected
should be true (and its nodes
nodeSelected
should also be 'true'). Or else whole parent nodes nodeSelected
should be true(along with it nodes).
So the result will be like this:
var resultArray = [
{
id:"11",
text: "Parent 1",
type:"Parent",
nodeSelected:false,
nodes: [
{
text: "Child 1",
parentId: "11",
id:"21",
nodeSelected:true,
type: "Child",
nodes: [
{
id:"36",
text: "Grandchild 1",
parentId: "21",
nodeSelected:true,
type: "Grandchild"
},
{
id:"38",
text: "Grandchild 2",
parentId: "21",
nodeSelected:true,
type: "Grandchild"
}
]
},
{
id:"43",
text: "Child 2",
nodeSelected:false,
parentId:"11",
type: "Child",
nodes: [
{
id:"52",
parentId:"43",
text: "Grandchild 1 of child 2",
nodeSelected:true,
type: "Grandchild"
}
]
}
]
},
{
id:"46",
text: "Parent 2",
nodeSelected:false,
type: "Parent"
},
{
id:"48",
text: "Parent 3",
nodeSelected:true,
type: "Parent",
node: [
{
id:"70",
text: "child 3",
parentId: "48",
type: "Child",
nodeSelected:true
}
]
}
];
( My try ) Although incomplete but something like this we can do
tree.forEach((Parent) => {
if (groupedIds.includes(Parent.id)) {
let isSomeChildSelected = Parent.nodes.some((loc) => groupedIds.includes(loc.id));
if (isSomeChildSelected) {
Parent.nodes.forEach((child) => {
if (groupedIds.includes(child.id)) {
let isSomeGrandChildSelected = child.nodes.some((grandchild) => groupedIds.includes(grandchild.id));
if (isSomeGrandChildSelected) {
child.nodes.forEach((grandchild) => {
if (groupedIds.includes(grandchild.id)) {
grandchild.isSelected = true;
}
})
} else {
child.isSelected = true;
child.nodes.forEach((grandchild) => {
grandchild.isSelected = true;
})
}
}
})
} else {
Parent.isSelected = true;
Parent.nodes.forEach((child) => {
child.isSelected = true;
child.nodes.forEach((grandchild) => {
grandchild.isSelected = true;
})
})
}
}
})
The above tried method solves the issue to some extent, but it is a bit complex.
Any help would be much appreciated. Thanks!
I'm not going to do it for you (not out of malice, just because I'm not 100% sure I understand the question,). but I'll hopefully give you a big point in the right direction.
When traversing trees, 90% of the time you need something called recursion. Recursion looks like this:
function walk(items){
items.forEach(items => {
if(item.hasChildrenOrSomething){
// notice the function calls itself:
walk(item.children);
}
// Do something with item
});
}
walk(tree);
There is one important thing to note here, which is that if you do some logic after calling the function inside itself, all the children of the current item will have that logic applied. So, here we go – in your case you want something like this:
const walk = (branch) => {
branch.forEach(node => {
// Check if this object even has children:
if(node.hasOwnProperty('nodes') && node.nodes.length){
walk(node.nodes);
// Do your node.nodes.every check here
}
// Now check if this is in the array
});
}
walk(tree);
If you've used recursion before, sorry, this whole post was probably just super patronising and has missed the point of your question. If you haven't, then can I just say I am a) jealous of you for getting to experience the feeling of something so elegant for the first time and b) sorry for you for having to unravel the mind boggling nature of them.
This gives me output what I want(with recursion):
var tree = [ { id:"11", text: "Parent 1", type:"Parent", nodeSelected:false, nodes: [ { text: "Child 1", parentId: "11", id:"21", nodeSelected:false, type: "Child", nodes: [ { id:"36", text: "Grandchild 1", parentId: "21", nodeSelected:false, nodes:[], type: "Grandchild" }, { id:"38", text: "Grandchild 2", parentId: "21", nodes:[], nodeSelected:false, type: "Grandchild" } ] }, { id:"43", text: "Child 2", nodeSelected:false, parentId:"11", type: "Child", nodes: [ { id:"52", parentId:"43", text: "Grandchild 1 of child 2", nodeSelected:false, nodes:[], type: "Grandchild" } ] } ] }, { id:"46", text: "Parent 2", nodeSelected:false, type: "Parent", nodes:[] }, { id:"48", text: "Parent 3", nodeSelected:false, type: "Parent", nodes: [ { id:"70", text: "child 3", parentId: "48", type: "Child", nodeSelected:false, nodes:[] } ] } ]; groupedIds=["11","21","43","52","48"]; var selectAllNode=array=> array.forEach((value)=>{ value.nodeSelected=true; value.nodes? selectAllNode(value.nodes): [] }); var getFilteredData = array => array.forEach((ele)=>{ if(groupedIds.includes(ele.id)){ let isSomeSelected = ele.nodes.some((val)=>groupedIds.includes(val.id)); if(isSomeSelected){ getFilteredData(ele.nodes); } else { ele.nodeSelected=true; selectAllNode(ele.nodes); } } }); getFilteredData(tree); console.log(tree);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.