I have an array of objects with 3 levels. I want to target the innermost child with property 'code'. If code is present, then update the child as well as the parent object with selected: true. If the property already is true, then sending in the same value should set the child to selected: false (toggle)
This is what I have going so far. If selected is true for a child, sending in another code should set selected: true for the corresponding child and selected: false for the child which had true for selected property.
Also, if selected is true for a child, defaultCollapsed property should be false for the child as well as parent and grandparent. Ifs elected is false for a child, defaultCollapsed property should be true for the child as well as parent and grandparent
const data = [{
"label": "Grand Parent 1",
"index": 0,
"code": "GRAND_PARENT_1",
"defaultCollapsed": true,
"items": [{
"id": 1,
"items": [{
"id": 100,
"label": "Child 1",
"url": "#CHILD_1",
"code": "CHILD_1",
},
{
"id": 200,
"label": "Child 2",
"url": "#CHILD_2",
"code": "CHILD_2"
},
{
"id": 300,
"label": "Child 3",
"url": "#CHILD_3",
"code": "CHILD_3"
},
{
"id": 400,
"label": "Child 4",
"url": "#CHILD_4",
"code": "CHILD_4"
}
],
"defaultCollapsed": true,
"label": "Parent 1",
"selected": true,
},
{
"id": 2,
"items": [],
"defaultCollapsed": true,
"label": "Parent 2"
},
{
"id": 3,
"items": [],
"defaultCollapsed": true,
"label": "Parent 3"
},
{
"id": 4,
"items": [],
"defaultCollapsed": true,
"label": "Parent 4"
}
]
},
{
"label": "Grand Parent 2",
"index": 1,
"code": "GRAND_PARENT_2",
"defaultCollapsed": true,
"items": []
},
{
"label": "Grand Parent 3",
"index": 2,
"code": "GRAND_PARENT_3",
"defaultCollapsed": true,
"items": []
}
]
function select(items, key, value) {
if (!Array.isArray(items)) {
return false;
}
for (const item of items) {
if (item.code === value || select(item.items, key, value)) {
item.selected = !item.selected;
item.defaultCollapsed = false;
return true;
}
}
return false;
}
function reset(items) {
if (!Array.isArray(items)) {
return;
}
for (const item of items) {
if (item.selected) {
reset(item.items);
item.selected = false;
break;
}
}
}
function resetAndSelect(data, key, value) {
reset(data);
select(data, key, value);
}
resetAndSelect(data, 'code', 'CHILD_1')
console.log('CHILD_1',data)
resetAndSelect(data, 'code', 'CHILD_2')
console.log('CHILD_2',data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
If code is CHILD_1:
[{
"label": "Grand Parent 1",
"index": 0,
"code": "GRAND_PARENT_1",
"defaultCollapsed": true,
"selected": true,
"items": [{
"id": 1,
"items": [{
"id": 100,
"label": "Child 1",
"url": "#CHILD_1",
"code": "CHILD_1",
"selected": true,
},
{
"id": 200,
"label": "Child 2",
"url": "#CHILD_2",
"code": "CHILD_2"
},
{
"id": 300,
"label": "Child 3",
"url": "#CHILD_3",
"code": "CHILD_3"
},
{
"id": 400,
"label": "Child 4",
"url": "#CHILD_4",
"code": "CHILD_4"
}
],
"defaultCollapsed": false,
"label": "Parent 1",
"selected": true,
},
{
"id": 2,
"items": [],
"defaultCollapsed": true,
"label": "Parent 2"
},
{
"id": 3,
"items": [],
"defaultCollapsed": true,
"label": "Parent 3"
},
{
"id": 4,
"items": [],
"defaultCollapsed": true,
"label": "Parent 4"
}
]
},
{
"label": "Grand Parent 2",
"index": 1,
"code": "GRAND_PARENT_2",
"defaultCollapsed": true,
"items": []
},
{
"label": "Grand Parent 3",
"index": 2,
"code": "GRAND_PARENT_3",
"defaultCollapsed": true,
"items": []
}
]
If the above output is the actual data, and the code is CHILD_1 again, I need to toggle the selected property of the child as well the corresponding parents.
[{
"label": "Grand Parent 1",
"index": 0,
"code": "GRAND_PARENT_1",
"defaultCollapsed": true,
"selected": false,
"items": [{
"id": 1,
"items": [{
"id": 100,
"label": "Child 1",
"url": "#CHILD_1",
"code": "CHILD_1",
"selected": false,
},
{
"id": 200,
"label": "Child 2",
"url": "#CHILD_2",
"code": "CHILD_2"
},
{
"id": 300,
"label": "Child 3",
"url": "#CHILD_3",
"code": "CHILD_3"
},
{
"id": 400,
"label": "Child 4",
"url": "#CHILD_4",
"code": "CHILD_4"
}
],
"defaultCollapsed": false,
"label": "Parent 1",
"selected": false,
},
{
"id": 2,
"items": [],
"defaultCollapsed": true,
"label": "Parent 2"
},
{
"id": 3,
"items": [],
"defaultCollapsed": true,
"label": "Parent 3"
},
{
"id": 4,
"items": [],
"defaultCollapsed": true,
"label": "Parent 4"
}
]
},
{
"label": "Grand Parent 2",
"index": 1,
"code": "GRAND_PARENT_2",
"defaultCollapsed": true,
"items": []
},
{
"label": "Grand Parent 3",
"index": 2,
"code": "GRAND_PARENT_3",
"defaultCollapsed": true,
"items": []
}
]
selected: trueorselected: false?