Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collapse and Expand Tree structure in Javascript

I need a help on collapse and Expand using Javascript. Here is my running code (.html)

 <h2>Test</h2>
  <html lang="en">
  <head>
     <META http-equiv="Content-Type" content="text/html; charset=utf-16">
     <title></title>
     <script type="text/javascript">  
        function toggleDisplay(element) 
        {       
          element.style.display = element.style.display === 'none' ? '' : 'none'; 
        };
        function toggleDisplayAll(elements) 
        { 
          for(var i=0; i<elements.length; i++)
           {
              toggleDisplay(elements[i]);
           }
        }   
     </script>
   </head>
   <body>  
    <ul>
      <a onclick="toggleDisplayAll(this.parentNode.getElementsByTagName('ul')); return false;" href="#">Name:</a>
        <ul style="display:none;">
        <a onclick="toggleDisplayAll(this.parentNode.getElementsByTagName('ul')); return false;" href="#">Address: </a>
            <ul style="display:none;">
            <a onclick="toggleDisplayAll(this.parentNode.getElementsByTagName('li')); return false;" href="#">Subject: </a>
                <ul style="display:none;">
                    <li style="display:none;">Id
                    </li>
                </ul>
            </ul>
         </ul>
     </ul>
  </body>
 </html>

If you run this html, you will get out put as

 Name

on click of Name, it is showing all the child elements

 Name:
    Address:
        Subject:

On click of Subject it is showing Id

  Name:
    Address:
        Subject:
               . Id

What i want here is each child should open only on parent click.

When run the html, only Name will dispaly

  Name:

On click of Name, only Address will be displayed as a child element.

   Name:
        Address:

Onclick of Address, only Subject will display

   Name:
        Address:
            Subject:

Than finally on click of Subject, id will show up

   Name:
        Address:
            Subject:
                 . Id

How to implement this tree structure. what i am doing wrong here. please suggest me.

like image 378
user1893874 Avatar asked Jun 19 '15 19:06

user1893874


People also ask

How do you collapse in JavaScript?

Just add data-toggle="collapse" and a data-target to element to automatically assign control of a collapsible element. The data-target attribute accepts a CSS selector to apply the collapse to. Be sure to add the class collapse to the collapsible element. If you'd like it to default open, add the additional class in.

What is collapse tree?

collapse( parent ) collapses the nodes of the parent tree or tree node. If parent is a Tree object, then the top-level nodes in the tree display in a collapsed state.

What is the expand collapse button?

This pattern creates a button that toggles an element as hidden (collapsed) or not hidden (expanded). The element's current state and changes in the element's state are communicated to screen reader users.


2 Answers

Check this:

$('.expand').click(function() {
  $('ul', $(this).parent()).eq(0).toggle();
});
ul li ul {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li>
    <a class="expand">Root</a>
    <ul>
      <li>
        <a class="expand">Child</a>
        <ul>
          <li>
            <a class="expand">Super Child</a>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Edit

If you don't want to use jQuery, you can try this:

var expander = document.querySelectorAll('.expand');

for (var i = 0; i < expander.length; ++i) {
  expander[i].onclick = function() {
    var ul = this.parentElement.querySelectorAll('ul')[0];
    
    if (ul.offsetHeight > 0) {
      ul.style.display = 'none';
    } else {
      ul.style.display = 'block';
    }
  }
}
ul li ul {
  display: none;
}
    <ul>
      <li>
        <a class="expand">Root</a>
        <ul>
          <li>
            <a class="expand">Child</a>
            <ul>
              <li>
                <a class="expand">Super Child</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
like image 176
Nanang Mahdaen El-Agung Avatar answered Sep 29 '22 20:09

Nanang Mahdaen El-Agung


You want to target just the first child element, instead of looping through all of them. You should also try to separate your logic from your markup. Give unobtrusive JavaScript a read.

function toggle() {
  var ls = this.parentNode.getElementsByTagName('ul')[0],
      styles, display;

  if (ls) {
    styles = window.getComputedStyle(ls);
    display = styles.getPropertyValue('display');

    ls.style.display = (display === 'none' ? 'block' : 'none');
  }
}


var eles = document.querySelectorAll('.ele');

Array.prototype.slice.call(eles).forEach(function (e) {
  e.addEventListener('click', toggle);
});
ul ul {
  display: none;
}

.ele {
  cursor: pointer;
}

.ele:hover {
  color: red;
}
<ul>
  <li><span class="ele">One</span>
    <ul>
      <li><span class="ele">Two</span>
        <ul>
          <li><span class="ele">Three</span>
            <ul>
              <li><span class="ele">Four</span></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
like image 31
Oka Avatar answered Sep 29 '22 19:09

Oka