Skip to content

Instantly share code, notes, and snippets.

@M0r13n
Created September 2, 2020 14:57
Show Gist options
  • Save M0r13n/3e2f5235bf1166080c24baa2fb6d6c8d to your computer and use it in GitHub Desktop.
Save M0r13n/3e2f5235bf1166080c24baa2fb6d6c8d to your computer and use it in GitHub Desktop.
Recursive Multilevel, nested and numbered lists from JSON. This includes checkboxes that also check or un-check their child checkboxes on click.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="./style.css">
<title>Test</title>
</head>
<body>
<h1>Simple demo for a HTML ordered list</h1>
<form action="#" method="GET" id="listContainer">
</form>
<script>
const tree = [{
'name': 'One',
'children': [{
'name': 'One.One',
'children': [{
'name': 'One.One.one',
'children': [{
'name': 'One.One.one.One',
'children': []
},
{
'name': 'One.One.one.Two',
'children': []
},
{
'name': 'One.One.one.Three',
'children': []
},
]
},
{
'name': 'One.One.Twwo',
'children': []
}
]
},
{
'name': 'One.Two',
'children': []
}
]
},
{
'name': 'Two',
'children': []
},
{
'name': 'Three',
'children': []
},
];
function toggleSelectForChildren() {
// Check/Uncheck the element itself and all child input elements.
const checked = this.checked;
[...this.parentNode.getElementsByTagName('input')].forEach((elem) => {
elem.checked = checked;
});
}
function createCheckBox() {
// Create a checkbox dom element which also checks/unchecks all it's children on click.
let checkBox = document.createElement("input");
checkBox.type = "checkbox";
checkBox.addEventListener("click", toggleSelectForChildren);
return checkBox;
}
function createOl(parent = null) {
let ol = document.createElement("ol");
parent.appendChild(ol);
return ol;
}
function createLi(name, parent) {
let checkbox = createCheckBox();
let li = document.createElement("li");
let label = document.createElement("label");
label.innerText = name;
li.append(label)
li.prepend(checkbox);
parent.appendChild(li);
return li;
}
function isLeaf(node) {
return !node.children.length;
}
function traverse_tree(tree = [], parent) {
tree.forEach((node, index) => {
if (!index) {
parent = createOl(parent);
}
const li = createLi(node.name, parent);
if (!isLeaf(node)) {
traverse_tree(node.children, li);
}
});
}
// Add list elements to DOM
traverse_tree(tree, document.getElementById('listContainer'));
</script>
</body>
</html>
ol {
counter-reset: item;
}
ol>li {
counter-increment: item;
}
ol ol>li {
display: block;
}
ol ol>li:before {
content: counters(item, ".") ". ";
margin-left: -20px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment