JSFiddle - React, Tailwind, and code Playground

by dominagy

HTML

<ul id="myUL" class="level1">
  <li><span class="caret"></span><input type="checkbox" value="xyz" name="xyz">Beverages
    <ul class="level2">
      <li><input type="checkbox" value="xyz" name="xyz">Water</li>
      <li><input type="checkbox" value="xyz" name="xyz">Coffee</li>
      <li><span class="caret"></span><input type="checkbox" value="xyz" name="xyz">Tea
        <ul class="level3">
          <li><input type="checkbox" value="xyz" name="xyz">Black Tea</li>
          <li><input type="checkbox" value="xyz" name="xyz">White Tea</li>
          <li><span class="caret"></span><input type="checkbox" value="xyz" name="xyz">Green Tea
            <ul class="level4">
              <li><input type="checkbox" value="xyz" name="xyz">Sencha</li>
              <li><input type="checkbox" value="xyz" name="xyz">Gyokuro</li>
              <li><input type="checkbox" value="xyz" name="xyz">Matcha</li>
              <li><input type="checkbox" value="xyz" name="xyz">Pi Lo Chun</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

CSS

/* Remove default bullets */
ul,
#myUL {
  list-style-type: none;
}

/* Remove margins and padding from the parent ul */
#myUL {
  margin: 0;
  padding: 0;
}

/* Style the caret/arrow */
.caret {
  cursor: pointer;
  user-select: none;
  /* Prevent text selection */
}

/* Create the caret/arrow with a unicode, and style it */
.caret::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}

/* 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;
}

JavaScript

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");
  });
}

let checks = document.querySelectorAll('input[type="checkbox"]');
checks.forEach((box) => {
  box.addEventListener('change', (e) => {
    var level = e.target.parentNode.parentNode.className;
    if (level == 'level4') {
      if (e.target.checked) {
        e.target.parentNode.parentNode.parentNode.querySelector('input').checked = true;
        e.target.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector('input').checked = true;
        e.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector('input').checked = true;
      } else {
        e.target.parentNode.parentNode.parentNode.querySelector('input').checked = false;
        e.target.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector('input').checked = false;
        e.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector('input').checked = false;
      }
    }
  });
});