How to make a tree select option - reactjs - javascript

I want to make a select/option nested with a json:
{
"id": 11,
"title": "A",
"parent_id": null,
"is_active": 1,
"children": [
{
"id": 12,
"title": "B",
"parent_id": 11,
"is_active": 1,
"children": [
{
"id": 13,
"title": "C",
"parent_id": 12,
"is_active": 1
},
{
"id": 14,
"title": "D",
"parent_id": 12,
"is_active": 1
},
{
"id": 15,
"title": "G",
"parent_id": 12,
"is_active": 1
},
{
"id": 16,
"title": "H",
"parent_id": 12,
"is_active": 1
},
{
"id": 62,
"title": "I",
"parent_id": 12,
"is_active": 1
}
]
},
{
"id": 17,
"title": "J",
"parent_id": 11,
"is_active": 1,
"children": [
{
"id": 18,
"title": "K",
"parent_id": 17,
"is_active": 1
},
{
"id": 19,
"title": "L",
"parent_id": 17,
"is_active": 1
},
{
"id": 20,
"title": "M",
"parent_id": 17,
"is_active": 1
},
{
"id": 21,
"title": "N",
"parent_id": 17,
"is_active": 1
}
]
}
]
}
I want to create below result:
<select>
<optgroup label=“A”>
<optgroup label=“B”>
<option>C</option>
<option>D</option>
<option>G</option>
</optgroup>
<optgroup label=“J”>
<option>K</option>
<option>L</option>
<option>M</option>
</optgroup>
</optgroup>
</select>
my code:
console.log(this.makeTreeOptionSele(undefined,data))
makeTreeOptionSele(result, obj) {
if (obj.children) {
result += "<optgroup label={"+obj.title+"}>"
{this.getOptionChilds(obj.children)}
"</optgroup>"
}
if(result)
return result
}
getOptionChilds(childrens) {
var result = null
for (var i = 0; i < childrens.length; ++i) {
var child = childrens[i]
result +="<option value={"+child.id+"}>{"+child.title+"}</option>"
if (child.children) {
return this.makeTreeOptionSele(result, child)
}
}
return result
}
but it does't return result.

function makeTreeOption(tree) {
let ouput = `<optgroup label="${tree.title}">`;
if (tree['children']) {
tree.children.forEach(children => {
if (children['children']) {
ouput += makeTreeOption(children);
} else {
ouput += `<option>${children.title}</option>`;
}
});
}
ouput += `</optgroup>`;
return ouput;
}

Related

How to handle complex tree array and traverse new arrays?

Object index 0:
If select===1, the third-level array length have two select===1, the two-level push to selected:[8,9] and checkedAll:true
the one-level checkedAll:true and push to selected:[7]
Object index 1: Same as above Object index 0
Object index 2:
If select===1, the two-level push to selected:[15], the third-level child array length > two-level array selected length, indeterminate:true
and the one-level indeterminate:true
I am trying to solve the complex json, don't know how to implement the following result array.
The correct result is printed as follows
[{
"id": 1,
"pid": 0,
"name": "a",
"select": 0,
"checkedAll": true,
"indeterminate": false,
"selected": [7],
"child": [{
"id": 7,
"pid": 1,
"name": "a-1",
"select": 1,
"checkedAll": true,
"indeterminate": false,
"selected": [8, 9],
"child": [{
"id": 8,
"pid": 7,
"name": "a-1-2",
"select": 1
},
{
"id": 9,
"pid": 7,
"name": "a-2-2",
"select": 1
}
]
}]
},
{
"id": 2,
"pid": 0,
"name": "b",
"select": 1,
"checkedAll": true,
"indeterminate": false,
"selected": [10],
"child": [{
"id": 10,
"pid": 2,
"name": "b-1",
"select": 1,
"checkedAll": true,
"indeterminate": false,
"selected": [11, 12],
"child": [{
"id": 11,
"pid": 10,
"name": "b-1-1",
"select": 1
},
{
"id": 12,
"pid": 10,
"name": "b-1-2",
"select": 1
}
]
}]
},
{
"id": 3,
"pid": 0,
"name": "c",
"select": 0,
"checkedAll": false,
"indeterminate": true,
"selected": [],
"child": [{
"id": 13,
"pid": 3,
"name": "c-1",
"select": 1,
"checkedAll": false,
"indeterminate": true,
"selected": [15],
"child": [{
"id": 14,
"pid": 13,
"name": "c-1-1",
"select": 0
},
{
"id": 15,
"pid": 13,
"name": "c-1-2",
"select": 1
}
]
}]
}
]
My code:
var result = [{
"id": 1,
"pid": 0,
"name": "a",
"select": 0,
"child": [{
"id": 7,
"pid": 1,
"name": "a-1",
"select": 1,
"child": [{
"id": 8,
"pid": 7,
"name": "a-1-2",
"select": 1
},
{
"id": 9,
"pid": 7,
"name": "a-2-2",
"select": 1
}
]
}]
},
{
"id": 2,
"pid": 0,
"name": "b",
"select": 0,
"child": [{
"id": 10,
"pid": 2,
"name": "b-1",
"select": 0,
"child": [{
"id": 11,
"pid": 10,
"name": "b-1-1",
"select": 1
},
{
"id": 12,
"pid": 10,
"name": "b-1-2",
"select": 1
}
]
}]
},
{
"id": 3,
"pid": 0,
"name": "c",
"select": 0,
"child": [{
"id": 13,
"pid": 3,
"name": "c-1",
"select": 1,
"child": [{
"id": 14,
"pid": 13,
"name": "c-1-1",
"select": 0
},
{
"id": 15,
"pid": 13,
"name": "c-1-2",
"select": 1
}
]
}]
}
]
var selected = []
for (let i = 0; i < result.length; i++) {
const a1 = result[i].child
for (let j = 0; j < a1.length; j++) {
console.log(a1[j].name)
const a2 = a1[j].child
for (let k = 0; k < a2.length; k++) {
if (a1[j].id === a2[k].pid) {
if (a2[k].select === 1) {
console.log(a1[j].id)
console.log(a2[k].name)
console.log('yyyyyyyy', a2[k].id)
}
}
}
}
}
console.log(result)
described as follows
And what about this (not sure if it is possible to change items order), you can click accept under voting arrows in case you like it:
var selected = [], result = input();
for (let i = 0; i < result.length; i++) {
const a1 = result[i].child
for (let j = 0; j < a1.length; j++) {
const a2 = a1[j].child
for (let k = 0; k < a2.length; k++) {
if (a1[j].id === a2[k].pid) {
if (a2[k].select === 1) {
let selected = a1[j].selected || [];
selected.push(a2[k].id)
a1[j].selected = selected;
if (selected.length == a2.length) {
result[i].checkedAll = true;
a1[j].checkedAll = true;
}
result[i].selected = a1[j].id;
}
}
}
result[i].indeterminate = !result[i].checkedAll;
a1[j].indeterminate = !a1[j].checkedAll;
}
}
console.log(JSON.stringify(result, null, 2))
function input() {
return [{
"id": 1,
"pid": 0,
"name": "a",
"select": 0,
"child": [{
"id": 7,
"pid": 1,
"name": "a-1",
"select": 1,
"child": [{
"id": 8,
"pid": 7,
"name": "a-1-2",
"select": 1
},
{
"id": 9,
"pid": 7,
"name": "a-2-2",
"select": 1
}
]
}]
},
{
"id": 2,
"pid": 0,
"name": "b",
"select": 0,
"child": [{
"id": 10,
"pid": 2,
"name": "b-1",
"select": 0,
"child": [{
"id": 11,
"pid": 10,
"name": "b-1-1",
"select": 1
},
{
"id": 12,
"pid": 10,
"name": "b-1-2",
"select": 1
}
]
}]
},
{
"id": 3,
"pid": 0,
"name": "c",
"select": 0,
"child": [{
"id": 13,
"pid": 3,
"name": "c-1",
"select": 1,
"child": [{
"id": 14,
"pid": 13,
"name": "c-1-1",
"select": 0
},
{
"id": 15,
"pid": 13,
"name": "c-1-2",
"select": 1
}
]
}]
}
];
}

How to combine and select JSON calls?

How to combine 2 json and appear together? If I choose one that has childern (like click MEN button), then childern in MEN will appear. But if element don't have childern, then the click function is not active.
And if I click the back button, it will bring up the previous menu.
So, the first time, I want to bring up
MEN
WOMEN
KIDS
Customer Care
Contact
And if I click the "MEN" button, will appear
back
accesoris
cloting
shoes
If I click the "back" button, it will return 1 step earlier. Not returning, like the first time.
You can see, This is my imagination to combine 2 json. I don't know how to combine 2 json. Maybe like this
$.each(first, second, function(i, value) {
var first = [{
"id": 1,
"text": "MEN",
"children": [{
"id": 10,
"text": "back"
},
{
"id": 11,
"text": "accesoris",
"children": [{
"id": 110,
"text": "back"
},
{
"id": 111,
"text": "hat",
},
{
"id": 112,
"text": "belt",
}
]
},
{
"id": 12,
"text": "cloting",
"children": [{
"id": 120,
"text": "back"
},
{
"id": 121,
"text": "blazer",
},
{
"id": 122,
"text": "pants",
}
]
},
{
"id": 13,
"text": "shoes",
"children": [{
"id": 130,
"text": "back"
},
{
"id": 131,
"text": "oxford",
},
{
"id": 132,
"text": "chukka",
}
]
}
]
},
{
"id": 2,
"text": "WOMEN",
"children": [{
"id": 20,
"text": "back"
},
{
"id": 21,
"text": "accesoris",
"children": [{
"id": 210,
"text": "back"
},
{
"id": 211,
"text": "ring",
},
{
"id": 212,
"text": "glove",
}
]
},
{
"id": 22,
"text": "cloting",
"children": [{
"id": 220,
"text": "back"
},
{
"id": 221,
"text": "tshirt",
},
{
"id": 222,
"text": "dress",
}
]
},
{
"id": 23,
"text": "shoes",
"children": [{
"id": 230,
"text": "back"
},
{
"id": 231,
"text": "sandals",
},
{
"id": 232,
"text": "heels",
}
]
}
]
},
{
"id": 3,
"text": "KIDS"
}
]
var second = [{
"id": 1,
"text": "Customer Care",
"children": [{
"id": 10,
"text": "back"
},
{
"id": 11,
"text": "Product Information"
},
{
"id": 12,
"text": "Payment Information"
},
{
"id": 13,
"text": "Your Order"
}]
},
{
"id": 2,
"text": "Contact",
"children": [{
"id": 20,
"text": "back"
},
{
"id": 21,
"text": "Careers"
},
{
"id": 22,
"text": "Affiliates"
}]
}
]
// Appears the first time
var text = [];
$.each(first, function(i, value) {
text += '<a>' + value.text + '</a><br>';
$('.result').html(text);
});
// Im not sure its correct, because im using first and second together
// var text = [];
// $.each(first, second, function(i, value) {
// text[i] += '<a>' + value.text + '</a><br>';
// $('.result').html(text[i]);
// });
// Function if a button is pressed
$(document).click('a', function(e) {
if ($(this).text() == 'back') {
// Go back one step, not back to the beginning
} else {
// function text() ----> $('.result').html(text);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="result"></div>
If you want to combine two arrays together you can just use concat.
var fullList = first.concat(second);
ok so this a jQuery version
var
first = [
{ "id": 1, "text": "MEN", "children": [
{ "id": 10, "text": "back" },
{ "id": 11, "text": "accesoris", "children": [
{ "id": 110, "text": "back" },
{ "id": 111, "text": "hat" },
{ "id": 112, "text": "belt" }
]},
{ "id": 12, "text": "cloting", "children": [
{ "id": 120, "text": "back" },
{ "id": 121, "text": "blazer" },
{ "id": 122, "text": "pants" }
]},
{ "id": 13, "text": "shoes", "children": [
{ "id": 130, "text": "back" },
{ "id": 131, "text": "oxford" },
{ "id": 132, "text": "chukka" }
]}
]},
{ "id": 2, "text": "WOMEN", "children": [
{ "id": 20, "text": "back" },
{ "id": 21, "text": "accesoris", "children": [
{ "id": 210, "text": "back" },
{ "id": 211, "text": "ring" },
{ "id": 212, "text": "glove" }
]},
{ "id": 22, "text": "cloting", "children": [
{ "id": 220, "text": "back" },
{ "id": 221, "text": "tshirt" },
{ "id": 222, "text": "dress" }
]},
{ "id": 23, "text": "shoes", "children": [
{ "id": 230, "text": "back" },
{ "id": 231, "text": "sandals" },
{ "id": 232, "text": "heels" }
]}
]},
{ "id": 3, "text": "KIDS" }
]
,
second = [
{ "id": 1, "text": "Customer Care", "children": [
{ "id": 10, "text": "back" },
{ "id": 11, "text": "Product Information" },
{ "id": 12, "text": "Payment Information" },
{ "id": 13, "text": "Your Order" }
]},
{ "id": 2, "text": "Contact", "children": [
{ "id": 20, "text": "back" },
{ "id": 21, "text": "Careers" },
{ "id": 22, "text": "Affiliates" }
]}
];
;
const
fullList = first.concat(second) ,
$myList = $('#my-List') ;
var
List_Level = [] ,
current_List = fullList ;
function ShowList_F()
{
let xList = fullList;
for (let x=0, xMax=List_Level.length; x<xMax; x++)
{
xList = xList[ List_Level[x] ].children;
}
$myList.empty()
current_List = xList;
for (let i=0, iMax=xList.length; i<iMax; i++)
{
let aClass = 'levelentry' + (xList[i].hasOwnProperty('children')?' PLUS':''); // other possibility
$myList.append( `<li class="root-level"><a class="${aClass}" data-ref="${i}">${xList[i].text}</a></li>`);
}
}
ShowList_F(); // first attempt
$myList.on( "click", "a", function(e)
{
e.preventDefault();
let xItem = parseInt( $(this).data('ref') );
if ($(this).text()==='back') // level Up
{
List_Level.pop()
ShowList_F();
}
else if (current_List[xItem].hasOwnProperty('children')) // level Down (and same test)
{
List_Level.push(xItem);
ShowList_F();
}
})
#my-List { cursor: pointer; list-style-type:none }
.PLUS::before { content: '- '}
.PLUS:hover::before { content: '+'}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="my-List"></ul>
so it's a complete solution, unfortunately I lost the habit of coding jQuery, so it's an ES6 solution (which I find really less complicated)
var
first = [
{ "id": 1, "text": "MEN", "children": [
{ "id": 10, "text": "back" },
{ "id": 11, "text": "accesoris", "children": [
{ "id": 110, "text": "back" },
{ "id": 111, "text": "hat" },
{ "id": 112, "text": "belt" }
]},
{ "id": 12, "text": "cloting", "children": [
{ "id": 120, "text": "back" },
{ "id": 121, "text": "blazer" },
{ "id": 122, "text": "pants" }
]},
{ "id": 13, "text": "shoes", "children": [
{ "id": 130, "text": "back" },
{ "id": 131, "text": "oxford" },
{ "id": 132, "text": "chukka" }
]}
]},
{ "id": 2, "text": "WOMEN", "children": [
{ "id": 20, "text": "back" },
{ "id": 21, "text": "accesoris", "children": [
{ "id": 210, "text": "back" },
{ "id": 211, "text": "ring" },
{ "id": 212, "text": "glove" }
]},
{ "id": 22, "text": "cloting", "children": [
{ "id": 220, "text": "back" },
{ "id": 221, "text": "tshirt" },
{ "id": 222, "text": "dress" }
]},
{ "id": 23, "text": "shoes", "children": [
{ "id": 230, "text": "back" },
{ "id": 231, "text": "sandals" },
{ "id": 232, "text": "heels" }
]}
]},
{ "id": 3, "text": "KIDS" }
]
,
second = [
{ "id": 1, "text": "Customer Care", "children": [
{ "id": 10, "text": "back" },
{ "id": 11, "text": "Product Information" },
{ "id": 12, "text": "Payment Information" },
{ "id": 13, "text": "Your Order" }
]},
{ "id": 2, "text": "Contact", "children": [
{ "id": 20, "text": "back" },
{ "id": 21, "text": "Careers" },
{ "id": 22, "text": "Affiliates" }
]}
];
;
const
fullList = first.concat(second)
,
myList = document.querySelector('#my-List')
,
Messager = {
_zone : document.getElementById('MsgZone'),
Text(msg) {
this._zone.textContent = msg;
setTimeout(that=>that._zone.textContent='', 900, this);
}
};
var
List_Level = [],
current_List = fullList,
LI_elm = document.createElement('li');
function ShowList_F()
{
let
xList = fullList,
showingTxt = '';
List_Level.forEach( x=>{
showingTxt += ` / ${xList[x].text}`
xList=xList[x].children
})
while( myList.firstChild )
{ myList.removeChild( myList.firstChild ); }
current_List = xList;
xList.forEach((e,i)=>{
let xLI = myList.appendChild(LI_elm.cloneNode(false));
xLI.dataset.ref = i.toString();
xLI.textContent = e.text;
if (e.text==='back') { xLI.className='back' }
})
Messager.Text(showingTxt)
}
ShowList_F(); // first attempt
myList.onclick = function(e)
{
if (!e.target.matches('li')) return;
e.stopPropagation();
let xItem = parseInt(e.target.dataset.ref);
if (e.target.textContent==='back')
{
List_Level.pop()
ShowList_F();
}
else if ( 'children' in current_List[ xItem ])
{
List_Level.push(xItem);
ShowList_F();
}
else
{
Messager.Text('nothing to do with this click')
}
}
#my-List { cursor: pointer; list-style-type:square }
#MsgZone, .back { font-size: 0.8em; font-style: italic }
<ul id="my-List"></ul>
<div id="MsgZone"></div>

How do I flatten a (forest of) trees?

I have a forest of trees of arbitrary height, more or less like this:
let data = [
{ "id": 2, "name": "AAA", "parent_id": null, "short_name": "A" },
{
"id": 10, "name": "BBB", "parent_id": null, "short_name": "B", "children": [
{
"id": 3, "name": "CCC", "parent_id": 10, "short_name": "C", "children": [
{ "id": 6, "name": "DDD", "parent_id": 3, "short_name": "D" },
{ "id": 5, "name": "EEE", "parent_id": 3, "short_name": "E" }
]
},
{
"id": 4, "name": "FFF", "parent_id": 10, "short_name": "F", "children": [
{ "id": 7, "name": "GGG", "parent_id": 4, "short_name": "G" },
{ "id": 8, "name": "HHH", "parent_id": 4, "short_name": "H" }
]
}]
}
];
And I'm trying to produce a representation of all the root-to-leaves paths, something like this
[
[
{
"id": 2,
"name": "AAA"
}
],
[
{
"id": 10,
"name": "B"
},
{
"id": 3,
"name": "C"
},
{
"id": 6,
"name": "DDD"
}
],
[
{
"id": 10,
"name": "B"
},
{
"id": 3,
"name": "C"
},
{
"id": 5,
"name": "EEE"
}
],
[
{
"id": 10,
"name": "B"
},
{
"id": 4,
"name": "F"
},
{
"id": 7,
"name": "GGG"
}
],
[
{
"id": 10,
"name": "B"
},
{
"id": 4,
"name": "F"
},
{
"id": 8,
"name": "HHH"
}
]
]
So I wrote the following code:
function flattenTree(node, path = []) {
if (node.children) {
return node.children.map(child => flattenTree(child, [...path, child]));
} else {
let prefix = path.slice(0, path.length - 1).map(n => ({ id: n.id, name: n.short_name }));
let last = path[path.length - 1];
return [...prefix, { id: last.id, name: last.name } ];
}
}
let paths = data.map(n => flattenTree(n, [n]));
but paths comes out with extra nesting, like this:
[
[
{
"id": 2,
"name": "AAA"
}
],
[
[
[
{
"id": 10,
"name": "B"
},
{
"id": 3,
"name": "C"
},
{
"id": 6,
"name": "DDD"
}
],
[
{
"id": 10,
"name": "B"
},
{
"id": 3,
"name": "C"
},
{
"id": 5,
"name": "EEE"
}
]
],
[
[
{
"id": 10,
"name": "B"
},
{
"id": 4,
"name": "F"
},
{
"id": 7,
"name": "GGG"
}
],
[
{
"id": 10,
"name": "B"
},
{
"id": 4,
"name": "F"
},
{
"id": 8,
"name": "HHH"
}
]
]
]
]
I lost count of the many ways in which I tried to fix this, but it does look like the algorithm should not produce the extra nesting -- or my eyes are just so crossed by now that I couldn't see my mistake if someone stuck their finger on it.
Can someone help? Feel free to peruse this JSFiddle https://jsfiddle.net/png7x9bh/66/
The extra nestings are created by map. map just wraps the results into an array and returns them, it doesn't care if it is called on child nodes or not. Use reduce and just concat (or push, whatever suits your performance) the results into the first level array directly:
let data = [{"id":2,"name":"AAA","parent_id":null,"short_name":"A"},{"id":10,"name":"BBB","parent_id":null,"short_name":"B","children":[{"id":3,"name":"CCC","parent_id":10,"short_name":"C","children":[{"id":6,"name":"DDD","parent_id":3,"short_name":"D"},{"id":5,"name":"EEE","parent_id":3,"short_name":"E"}]},{"id":4,"name":"FFF","parent_id":10,"short_name":"F","children":[{"id":7,"name":"GGG","parent_id":4,"short_name":"G"},{"id":8,"name":"HHH","parent_id":4,"short_name":"H"}]}]}];
function flattenTree(node, path = []) {
let pathCopy = Array.from(path);
pathCopy.push({id: node.id, name: node.name});
if(node.children) {
return node.children.reduce((acc, child) => acc.concat(flattenTree(child, pathCopy)), []);
}
return [pathCopy];
}
let result = data.reduce((result, node) => result.concat(flattenTree(node)), []);
console.log(JSON.stringify(result, null, 3));

Using angularjs forEach loops

I am getting this type of json in my $scope of angularjs:
$scope.someStuff = {
"id": 2,
"service": "bike",
"min": "22",
"per": "100",
"tax": "1",
"categoryservices": [
{
"id": 32,
"category": {
"id": 1,
"name": "software"
}
},
{
"id": 33,
"category": {
"id": 2,
"name": "hardware"
}
},
{
"id": 34,
"category": {
"id": 3,
"name": "waterwash"
}
}
]
}
I want to use angularjs forEach loop and i want to get only category name,
My expected output:
[{"name":"software"}, {"name":"hardware"}, {"name":"waterwash"}]
You can use Array.map()
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
$scope.someStuff.categoryservices.map((x) => { return { name: x.category.name}})
var obj = {
"id": 2,
"service": "bike",
"min": "22",
"per": "100",
"tax": "1",
"categoryservices": [{
"id": 32,
"category": {
"id": 1,
"name": "software"
}
},
{
"id": 33,
"category": {
"id": 2,
"name": "hardware"
}
},
{
"id": 34,
"category": {
"id": 3,
"name": "waterwash"
}
}
]
};
console.log(obj.categoryservices.map((x) => {
return {
name: x.category.name
}
}))
You can use map method by passing a callback function as parameter.
const someStuff = { "id": 2, "service": "bike", "min": "22", "per": "100", "tax": "1", "categoryservices": [ { "id": 32, "category": { "id": 1, "name": "software" } }, { "id": 33, "category": { "id": 2, "name": "hardware" } }, { "id": 34, "category": { "id": 3, "name": "waterwash" } } ] }
let array = someStuff.categoryservices.map(function({category}){
return {'name' : category.name}
});
console.log(array);

How to find all unique paths in tree structure

root1
child1
child2
grandchild1
grandchild2
child3
root2
child1
child2
grandchild1
greatgrandchild1
I have an object array like tree structure like above, I want to get all unique paths in like this
Food->Dry Food Items->Local Dry Food Items
Food->Dry Food Items->Thai Dry Food Items
Food->Dry Food Items->Others
Food->Fruits
------
------
This is my object
[
{
"id": 1,
"name": "Food",
"parent_id": 0,
"children": [
{
"id": 5,
"name": "Dry Food Items",
"parent_id": 1,
"children": [
{
"id": 11,
"name": "Local Dry Food Items",
"parent_id": 5
},
{
"id": 12,
"name": "Thai Dry Food Items",
"parent_id": 5
},
{
"id": 60,
"name": "Others",
"parent_id": 5
}
]
},
{
"id": 6,
"name": "Fruits",
"parent_id": 1
},
{
"id": 7,
"name": "LG Branded",
"parent_id": 1
},
{
"id": 8,
"name": "Meat",
"parent_id": 1
},
{
"id": 9,
"name": "Sea food",
"parent_id": 1
},
{
"id": 10,
"name": "Vegetables",
"parent_id": 1,
"children": [
{
"id": 14,
"name": "Local Vegetables",
"parent_id": 10
},
{
"id": 15,
"name": "Thai Vegetables",
"parent_id": 10
}
]
},
{
"id": 38,
"name": "Frozen",
"parent_id": 1
},
{
"id": 39,
"name": "IP Kitchen",
"parent_id": 1,
"children": [
{
"id": 40,
"name": "IP Meat",
"parent_id": 39
},
{
"id": 41,
"name": "IP Starter",
"parent_id": 39
},
{
"id": 42,
"name": "IP Ingredients",
"parent_id": 39
},
{
"id": 43,
"name": "IP Sauce",
"parent_id": 39
},
{
"id": 44,
"name": "IP Seafood",
"parent_id": 39
},
{
"id": 45,
"name": "IP Starter",
"parent_id": 39
},
{
"id": 46,
"name": "IP Desert",
"parent_id": 39
}
]
}
]
},
{
"id": 2,
"name": "Beverage",
"parent_id": 0,
"children": [
{
"id": 16,
"name": "Bar",
"parent_id": 2
},
{
"id": 17,
"name": "Coffee & Tea",
"parent_id": 2
},
{
"id": 18,
"name": "In Can",
"parent_id": 2
},
{
"id": 19,
"name": "Water",
"parent_id": 2
},
{
"id": 47,
"name": "IP Bar",
"parent_id": 2
}
]
},
{
"id": 3,
"name": "Disposable",
"parent_id": 0,
"children": [
{
"id": 21,
"name": "Disposable",
"parent_id": 3
}
]
},
{
"id": 4,
"name": "SOE",
"parent_id": 0,
"children": [
{
"id": 20,
"name": "Cleaning Materials",
"parent_id": 4
},
{
"id": 22,
"name": "Chinaware",
"parent_id": 4
}
]
}
];
I get to all the nodes in the tree
function traverse(categories) {
categories.forEach(function (category) {
if (category.children && category.children.length) {
traverse(category.children);
}
else {
}
}, this);
}
You can use recursion and create a function using forEach loop.
var arr = [{"id":1,"name":"Food","parent_id":0,"children":[{"id":5,"name":"Dry Food Items","parent_id":1,"children":[{"id":11,"name":"Local Dry Food Items","parent_id":5},{"id":12,"name":"Thai Dry Food Items","parent_id":5},{"id":60,"name":"Others","parent_id":5}]},{"id":6,"name":"Fruits","parent_id":1},{"id":7,"name":"LG Branded","parent_id":1},{"id":8,"name":"Meat","parent_id":1},{"id":9,"name":"Sea food","parent_id":1},{"id":10,"name":"Vegetables","parent_id":1,"children":[{"id":14,"name":"Local Vegetables","parent_id":10},{"id":15,"name":"Thai Vegetables","parent_id":10}]},{"id":38,"name":"Frozen","parent_id":1},{"id":39,"name":"IP Kitchen","parent_id":1,"children":[{"id":40,"name":"IP Meat","parent_id":39},{"id":41,"name":"IP Starter","parent_id":39},{"id":42,"name":"IP Ingredients","parent_id":39},{"id":43,"name":"IP Sauce","parent_id":39},{"id":44,"name":"IP Seafood","parent_id":39},{"id":45,"name":"IP Starter","parent_id":39},{"id":46,"name":"IP Desert","parent_id":39}]}]},{"id":2,"name":"Beverage","parent_id":0,"children":[{"id":16,"name":"Bar","parent_id":2},{"id":17,"name":"Coffee & Tea","parent_id":2},{"id":18,"name":"In Can","parent_id":2},{"id":19,"name":"Water","parent_id":2},{"id":47,"name":"IP Bar","parent_id":2}]},{"id":3,"name":"Disposable","parent_id":0,"children":[{"id":21,"name":"Disposable","parent_id":3}]},{"id":4,"name":"SOE","parent_id":0,"children":[{"id":20,"name":"Cleaning Materials","parent_id":4},{"id":22,"name":"Chinaware","parent_id":4}]}]
function getNames(data) {
var result = [];
function loop(data, c) {
data.forEach(function (e) {
var name = !c.length ? e.name : c + '->' + e.name;
if (e.children) { loop(e.children, name); }
else {
result.push({ name: name });
}
});
}
loop(data, '');
return result;
}
console.log(getNames(arr))

Categories

Resources