Reputation: 71
i'm facing problem to construct a tree structure with details tag in javascript
my expected tree structure
<ul>
<li>Root
<ul>
<li>First level item 1</li>
<li>
First level item 2
<ul>
<li>second level item1</li>
</ul>
</li>
</ul>
</li>
with details tag i'm not able to get the desired structure which like below one
My expected result(when expanded or collapsed):
<ul>
<li>Root
<ul>
<li>First level item 1</li>
<li>
First level item 2
<ul>
<li>second level item1</li>
</ul>
</li>
</ul>
</li>
Note: i want to get desired structure with <details>
tag only
Here is what i have tried:
Question: i want to get proper nesting structure with <details>
tag(s)
var treeList = [
{
"parentId": 0,
"id": 1,
"name": "Root"
},
{
"parentId": 1,
"id": 2,
"name": "First Level item 1"
},
{
"parentId": 1,
"id": 3,
"name": "First Level item 2"
},
{
"parentId": 3,
"id": 4,
"name": "second Level item 1"
}
];
var getTreeStrucureList = dataset => {
var hashTable = Object.create(null);
dataset.forEach(function(aData){
hashTable[aData.id] = {...aData, childNodes: []};
});
var dataTree = [];
dataset.forEach(aData => {
if(aData.parentId) { hashTable[aData.parentId].childNodes.push(hashTable[aData.id]);}
else { dataTree.push(hashTable[aData.id]); }
// console.log(ul);
});
//console.log(dataTree);
return dataTree;
};
var getListItems = dataset => {
// Create a string containing the items for this list
return dataset.map(item => {
// Build a nested UL string by calling getTreeStrucureTemplate on this objects children
var nested = getTreeStrucureTemplate(item.childNodes || [])
// Build the current item and add any nested lists
return `<summary >
${item.name}
</summary>${ nested }`
}).join('') // Join the items into a single string
}
var getTreeStrucureTemplate = dataset => {
// Only wrap the list in UL if it has contents
if (dataset.length) {
return `<details>${ getListItems(dataset) }</details>`
} else {
return '';
}
};
var nestedTreeList = getTreeStrucureList(treeList);
//console.log('tree list ',nestedTreeList);
$('#tree').append(getTreeStrucureTemplate(nestedTreeList));
#tree{
background: yellow;
//height:50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tree"></div>
<p>Expected tree should look like below one(Above tree structure is different)</p>
<ul>
<li>Root
<ul>
<li>First level item 1</li>
<li>
First level item 2
<ul>
<li>second level item1</li>
</ul>
</li>
</ul>
</li>
Upvotes: 0
Views: 581
Reputation: 3371
I've taken this to mainly be an HTML question rather than a JS one. Your code seems to produce a block of HTML like:
<details>
<summary>Root</summary>
<details>
<summary>First Level item 1</summary>
<summary>First Level item 2</summary>
<details>
<summary>second Level item 1</summary>
</details>
</details>
</details>
From looking at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details it's probably not valid to have more than one summary element per details element, so perhaps it would be worth trying something like:
details > details {
padding-left: 10px;
}
details span::before {
content: "*";
padding-right: 10px;
padding-left: 10px;
}
<details>
<summary>Root</summary>
<span>First Level item 1</span>
<details>
<summary>First Level item 2</summary>
<details>
<summary>second Level item 1</summary>
</details>
</details>
</details>
Edit: worth noting the "First Level item 1" has been moved out of the second details element.
Upvotes: 1