title: How do display a collapsible tree in AngularJS + Bootstrap
body: <p>I am building a web app where I need to display a tree using lists.  My basic structure looks like this:</p>
  
  <pre><code>* Node 1
      * Node 1.1
          * Node 1.1.1
              * Node 1.1.1.1
          * Node 1.1.2
      * Node 1.2
  </code></pre>
  
  <p><a href="http://jsfiddle.net/QffFm/1/">http://jsfiddle.net/QffFm/1/</a></p>
  
  <p>I'm trying to find something in angular or bootstrap that I can use such that:</p>
  
  <ul>
  <li>At first view of the list, it is expanded up to the third layer.  In my fiddle, I would want to see Node 1, Node 1.1, Node 1.1.1, Node 1.1.2 and Node 1.2 (all but the 4th layer - Node 1.1.1.1)</li>
  <li>On clicking on the list-style icon (not the word name of the node) The node collapses or expands </li>
  <li>Ideally, I would love for the icon to change also dependent on if the item is expanded.  A right arrow if there is more underneath, a down arrow if it is already expanded, and maybe a regular list item if there are no children</li>
  </ul>
  
  <p>I am very new to AngularJS and still quite new to Bootstrap as well.  I see that Angular has an accordion function which doesn't seem to quite handle everything I need it to.  </p>
  
  <p>I would love some direction on the best approach before I code a lot of logic into my web app that handles the different cases.  I think this must be a common problem so perhaps there is something ready made that I can utilize.  Any guidance would be much appreciated.</p>
  
  <p>HTML code:</p>
  
  <pre><code>&lt;div ng-app="myApp" ng-controller="controller"&gt;
      &lt;my-directive&gt;&lt;/my-directive&gt;
      &lt;table style="width: 100%"&gt;&lt;tbody&gt;&lt;td&gt;
          &lt;tree items="tree"&gt;&lt;/tree&gt;
      &lt;/td&gt;&lt;/tbody&gt;&lt;/table&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>Angular code:</p>
  
  <pre><code>var app = angular.module('myApp', []);
  
  app.controller('controller', function ($scope){ 
  
      $scope.tree=[{"name":"Node 1","items":[{"name":"Node 1.1","items":[{"name":"Node 1.1.1","items":[{"name":"Node 1.1.1.1","items":[]}]},{"name":"Node 1.1.2","items":[]}]},{"name":"Node 1.2","items":[]}]}];
  
  });
  app.directive('tree', function() {
      return {
          template: '&lt;ul&gt;&lt;tree-node ng-repeat="item in items"&gt;&lt;/tree-node&gt;&lt;/ul&gt;',
          restrict: 'E',
          replace: true,
          scope: {
              items: '=items',
          }
      };
  });
  
  app.directive('treeNode', function($compile) {
      return { 
          restrict: 'E',
          template: '&lt;li &gt;{{item.name}}&lt;/li&gt;',
          link: function(scope, elm, attrs) {
          if (scope.item.items.length &gt; 0) {
              var children = $compile('&lt;tree items="item.items"&gt;&lt;/tree&gt;')(scope);
              elm.append(children);
          }
      }
      };
  });
  </code></pre>