Problem:
I’m currently deveoling an asp.net core web app with html and javascript.
The problem is that I’m trying to implement a treeview where each element is a checkbox, and when I click an element I want the child elements to be also selected.
You can see an example below:
And here is the code:
@using ProvaFormularis.Assets.TVItems;
@model IEnumerable<MeasurementModel>
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<style>
/* Remove default bullets */
ul, #myUL {
list-style-type: none;
}
/* Remove margins and padding from the parent ul */
#myUL {
margin: 0;
padding: 0;
overflow-y: scroll;
height: 450px;
background: #f9f9f9;
}
/* Style the caret/arrow */
.caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
font-size: large;
}
/* Create the caret/arrow with a unicode, and style it */
.caret::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
font-size: large;
}
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.caret-down::before {
transform: rotate(90deg);
}
/* Hide the nested list */
.nested {
display: none;
}
/* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */
.active {
display: block;
}
li {
padding: 12px;
}
label {
font-size: large
}
input[type=checkbox] {
transform: scale(1.5);
}
</style>
<form>
<ul>
@foreach (TVStandard tvstandard in StaticClass.TVList.StandardsList)
{
<li>
<span class="caret"></span>
<input type="checkbox" class="checker" id=@tvstandard.Name name="Standard" value=@tvstandard.folderName unchecked>
<label for=@tvstandard.Name>@tvstandard.Name (@tvstandard.folderName)</label>
<ul class="nested">
@foreach(TVSection tvsection in tvstandard.Children)
{
<li>
<span class="caret"></span>
<input type="checkbox" class="checker" id=@tvsection.Name name="Section" value=@tvsection.scriptName unchecked>
<label for=@tvsection.Name>@tvsection.Name (@tvsection.scriptName)</label>
<ul class="nested">
@foreach (TVMode tvmode in tvsection.Children)
{
<li>
<span class="caret"></span>
<input type="checkbox" class="checker" id=@tvmode.Name name="Mode" value=@tvmode.Name unchecked>
<label for=@tvmode.Name>@tvmode.Name</label>
<ul class="nested">
@foreach (TVFreq tvfreq in tvmode.Children)
{
<li>
<input type="checkbox" class="checker" id=@tvfreq.Name name="Frequency" value=@tvfreq.ID unchecked>
<label for=@tvfreq.Name>@tvfreq.Name (@tvfreq.ID)</label>
</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>
</form>
<script>
var toggler = document.getElementsByClassName("caret");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function () {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("caret-down");
});
}
</script>
<script>
var toggler = document.getElementsByClassName("checker");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function () {
var lis = this.parentElement.getElementsByClassName(".nested").children;
var j;
for (j = 0; j < lis.length) {
var toggler2 = lis.getElementsByClassName("checker");
var k;
for (k = 0; k < toggler2.length; k++) {
toggler2[k].click();
}
}
});
}
</script>
So, does anybody know how to correctly implement this behavior?
Please note that the first script is the one that deplows the child elements and the second one is the one that must select the childs elements and does not work.
PD: I’ve tested the correct retrieval of click event and the click action of the checkboxes and it works fine. I’ve done that with these scripts:
<script>
var toggler = document.querySelectorAll("input[type=checkbox]");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].click();
}
</script>
<script>
var toggler = document.querySelectorAll("input[type=checkbox]");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function () {
this.checked = true;
});
}
</script>