2

I have a question about Tree view in pure HTML/CSS/JS files. I can make Tree view with HTML/CSS successfully and get help from w3school, you can see my code here: html file:

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");
 })
}
ul, .menu {
 list-style-type: none;
}
.menu {
  margin: 0;
  padding: 0;
}
.menu a {
  text-decoration: none;
}
.caret {
  cursor: pointer;
  user-select: none; /* Prevent text selection */
}
.caret::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
.caret-down::before {
  transform: rotate(90deg);
}
.nested {
  display: none;
}
 .active {
  display: block;
}
<ul class="menu">
<li><a href="#"><i class="fa fa-home"></i> Home</a></li>
<li class="caret">
  <a href="javascript:void(0);"><i class="fa fa-graduation-cap"></i> Tutorial</a>
  <ul class="nested">
    <li class="caret">
      <a href="javascript:void(0);"><i class="fa fa-chrome"></i> Web Development</a>
      <ul class="nested">
        <li><a href="#">Blog Project</a></li>
        <li><a href="#">CMS Project</a></li>
        <li><a href="#">Shop Project</a></li>
        <li><a href="#">E-learning Project</a></li>
        <li><a href="#">Automasion Project</a></li>
      </ul>
    </li>
    <li class="caret">
      <a href="javascript:void(0);"><i class="fa fa-server"></i> Network</a>
      <ul class="nested">
        <li><a href="#">Comptia</a></li>
        <li><a href="#">Windows</a></li>
        <li><a href="#">Linux</a></li>
        <li><a href="#">CISCO</a></li>
        <li><a href="#">MicroTik</a></li>
        <li><a href="#">Virtualization</a></li>
        <li><a href="#">Security</a></li>
      </ul>
    </li>
    <li class="caret">
      <a href="javascript:void(0);"><i class="fa fa-microchip"></i> IOT</a>
      <ul class="nested">
        <li><a href="#">Concept</a></li>
        <li><a href="#">Electronic</a></li>
        <li><a href="#">Sensor</a></li>
      </ul>
    </li>
  </ul>
</li>
<li><a href="#"><i class="fa fa-archive"></i> Projects</a></li>
<li><a href="#"><i class="fa fa-info-circle"></i> Resume</a></li>
<li><a href="#"><i class="fa fa-envelope-open"></i> Contact me</a></li>

But I have a problem in cascading (Open/close) them in js file, first time that I click on tutorials, that list will open without any problems, but after that when I click on one of the nested lists in it (web development) all of the tree from tutorials is closing.

2 Answers2

3

First thing your JS is correct, this this.parentElement.querySelector(".nested") alwayse targeting the first <ul>, just try to remove caret class from <li> and put it inside <a>, that's main that the click will be binded to <a> instead of<li>. or put it inside <span> as you want, it works as well. See the code snippet below :

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");
 })
}
ul, .menu {
 list-style-type: none;
}
.menu {
  margin: 0;
  padding: 0;
}
.menu a {
  text-decoration: none;
}
.caret {
  cursor: pointer;
  user-select: none; /* Prevent text selection */
}
.caret::before {
  content: "\25B6";
  color: black;
  display: inline-block;
  margin-right: 6px;
}
.caret-down::before {
  transform: rotate(90deg);
}
.nested {
  display: none;
}
 .active {
  display: block;
}
<ul class="menu">
<li><a href="#"><i class="fa fa-home"></i> Home</a></li>
<li>
  <a class="caret" href="javascript:void(0);"><i class="fa fa-graduation-cap"></i> Tutorial</a>
  <ul class="nested">
    <li>
      <a class="caret" href="javascript:void(0);"><i class="fa fa-chrome"></i> Web Development</a>
      <ul class="nested">
        <li><a href="#">Blog Project</a></li>
        <li><a href="#">CMS Project</a></li>
        <li><a href="#">Shop Project</a></li>
        <li><a href="#">E-learning Project</a></li>
        <li><a href="#">Automasion Project</a></li>
      </ul>
    </li>
    <li>
      <a class="caret" href="javascript:void(0);"><i class="fa fa-server"></i> Network</a>
      <ul class="nested">
        <li><a href="#">Comptia</a></li>
        <li><a href="#">Windows</a></li>
        <li><a href="#">Linux</a></li>
        <li><a href="#">CISCO</a></li>
        <li><a href="#">MicroTik</a></li>
        <li><a href="#">Virtualization</a></li>
        <li><a href="#">Security</a></li>
      </ul>
    </li>
    <li>
      <a class="caret" href="javascript:void(0);"><i class="fa fa-microchip"></i> IOT</a>
      <ul class="nested">
        <li><a href="#">Concept</a></li>
        <li><a href="#">Electronic</a></li>
        <li><a href="#">Sensor</a></li>
      </ul>
    </li>
  </ul>
</li>
<li><a href="#"><i class="fa fa-archive"></i> Projects</a></li>
<li><a href="#"><i class="fa fa-info-circle"></i> Resume</a></li>
<li><a href="#"><i class="fa fa-envelope-open"></i> Contact me</a></li>
Amine KOUIS
  • 1,686
  • 11
  • 12
0

The problem here is that you are binding the event on ul element. when the click happens it took this.parentElement (this is the element which click was binded on) so it is higher html level then you need. Place caret class on a element inside li. And the next problem is that they are using span element and you are using a element which is doing redirection by default so stopPropagation is needed as well.

  • TY my friend, I read your reference link, but I write it step by step by this link https://www.w3schools.com/howto/howto_js_treeview.asp i am new to js, i want to learn by creating sth so if you can help me in another way i really appreciate you – Mohammad Kiyan Mar 14 '19 at 13:48
  • Ok, we have to go deeper :). the problem here is that you are binding the event on ul element. But in the example event is binded to element inside ul element so this.parentElement returns correct element with .nested class – Pavel Kratochvil Mar 14 '19 at 13:55