AngularJS filter not expanding filtered nodes
<p>I'm using <a href="https://github.com/tchatel/angular-treeRepeat">https://github.com/tchatel/angular-treeRepeat</a> and am attempting to filter nodes that have not expanded. So I've modified this code to include AngularJS filter : </p>

<p>treeRepeat.html : </p>

<pre><code>&lt;p id="expand-collapse-all"&gt;
    &lt;a href="" ng-click="expandAll()"&gt;Expand all&lt;/a&gt;
    &lt;a href="" ng-click="collapseAll()"&gt;Collapse all&lt;/a&gt;
&lt;/p&gt;


Filter : &lt;input ng-model="myFilter" type="text"&gt;

&lt;ul frang-tree&gt;
  &lt;li frang-tree-repeat="node in treeData | filter:myFilter"&gt;
      &lt;div&gt;&lt;span class="icon"
                 ng-class="{collapsed: node.collapsed, expanded: !node.collapsed}"
                 ng-show="node.children &amp;&amp; node.children.length &gt; 0"
                 ng-click="node.collapsed = !node.collapsed"&gt;&lt;/span&gt;
           &lt;span class="label"
                 ng-class="{folder: node.children &amp;&amp; node.children.length &gt; 0}"
                 ng-bind="node.label"
                 ng-click="action(node)"&gt;&lt;/span&gt;
      &lt;/div&gt;
      &lt;ul ng-if="!node.collapsed &amp;&amp; node.children &amp;&amp; node.children.length &gt; 0"
          frang-tree-insert-children="node.children  | filter:myFilter"&gt;&lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</code></pre>

<p>This works as expected if all of the tree nodes are expanded : 
Line 20 on controllers.js : </p>

<pre><code>$scope.treeData = JSON.parse("[ { \"label\": \"root\", \"children\": [ { \"label\": \"folder A\", \"collapsed\": true, \"children\": [ { \"label\": \"folder B\", \"collapsed\": true, \"children\": [ { \"label\": \"file B1\", \"collapsed\": true }, { \"label\": \"file B2\", \"collapsed\": true } ] }, { \"label\": \"file A1\", \"collapsed\": true }, { \"label\": \"file A2\", \"collapsed\": true }, { \"label\": \"file A3\", \"collapsed\": true }, { \"label\": \"file A4\", \"collapsed\": true } ] }, { \"label\": \"folder C\", \"collapsed\": true, \"children\": [ { \"label\": \"folder D\", \"collapsed\": true, \"children\": [ { \"label\": \"folder E\", \"collapsed\": true, \"children\": [ { \"label\": \"file E1\", \"collapsed\": true }, { \"label\": \"file E2\", \"collapsed\": true }, { \"label\": \"file E3\", \"collapsed\": true } ] } ] }, { \"label\": \"folder F\", \"collapsed\": true, \"children\": [ { \"label\": \"file F1\", \"collapsed\": true }, { \"label\": \"file F2\", \"collapsed\": true } ] }, { \"label\": \"file C1\", \"collapsed\": true } ] }, { \"label\": \"folder G\", \"collapsed\": true, \"children\": [ { \"label\": \"file G1\", \"collapsed\": true }, { \"label\": \"file G2\", \"collapsed\": true }, { \"label\": \"file G3\", \"collapsed\": true }, { \"label\": \"file G4\", \"collapsed\": true } ] }, { \"label\": \"folder H\", \"collapsed\": true, \"children\": [ { \"label\": \"file H1\", \"collapsed\": true }, { \"label\": \"file H2\", \"collapsed\": true }, { \"label\": \"file H3\", \"collapsed\": true } ] } ] } ]");
</code></pre>

<p>But if the nodes are collapsed then the matched nodes expanded / viewable. The tree remains collapsed. Config for collapsed nodes : 
Line 21 on controllers.js : </p>

<pre><code>$scope.treeData = JSON.parse("[ { \"label\": \"root\", \"children\": [ { \"label\": \"folder A\", \"collapsed\": true, \"children\": [ { \"label\": \"folder B\", \"collapsed\": true, \"children\": [ { \"label\": \"file B1\", \"collapsed\": true }, { \"label\": \"file B2\", \"collapsed\": true } ] }, { \"label\": \"file A1\", \"collapsed\": true }, { \"label\": \"file A2\", \"collapsed\": true }, { \"label\": \"file A3\", \"collapsed\": true }, { \"label\": \"file A4\", \"collapsed\": true } ] }, { \"label\": \"folder C\", \"collapsed\": true, \"children\": [ { \"label\": \"folder D\", \"collapsed\": true, \"children\": [ { \"label\": \"folder E\", \"collapsed\": true, \"children\": [ { \"label\": \"file E1\", \"collapsed\": true }, { \"label\": \"file E2\", \"collapsed\": true }, { \"label\": \"file E3\", \"collapsed\": true } ] } ] }, { \"label\": \"folder F\", \"collapsed\": true, \"children\": [ { \"label\": \"file F1\", \"collapsed\": true }, { \"label\": \"file F2\", \"collapsed\": true } ] }, { \"label\": \"file C1\", \"collapsed\": true } ] }, { \"label\": \"folder G\", \"collapsed\": true, \"children\": [ { \"label\": \"file G1\", \"collapsed\": true }, { \"label\": \"file G2\", \"collapsed\": true }, { \"label\": \"file G3\", \"collapsed\": true }, { \"label\": \"file G4\", \"collapsed\": true } ] }, { \"label\": \"folder H\", \"collapsed\": true, \"children\": [ { \"label\": \"file H1\", \"collapsed\": true }, { \"label\": \"file H2\", \"collapsed\": true }, { \"label\": \"file H3\", \"collapsed\": true } ] } ] } ]");
</code></pre>

<p>Plunkr : <a href="https://plnkr.co/edit/CtXlRfdreolTTc018c0A?p=preview">https://plnkr.co/edit/CtXlRfdreolTTc018c0A?p=preview</a></p>

<p>Do I need to manually expand the nodes as the user types or is there an angular config I can use to expand these nodes ?</p>

<p>I've tried adding a custom function that fires everytime user types : </p>

<pre><code>  function matchChildNode(objData , parentNode) {

        angular.forEach(objData, function(childNode, key) {

                var searchText = "";
                //AngularJS does not initialise the searchText var until used. As the function is re-initialised for every node
                //need to check if is undefined
                if ($scope.searchText == undefined) {
                    searchText = ""
                } else {
                    searchText = $scope.searchText
                }

                if (searchText.toLowerCase() === childNode.label.toLowerCase()) {
                    parentNode.collapsed = false
                }       

                matchChildNode(childNode.children , childNode);

  });
  } 
}
</code></pre>

<p>But this is very inefficient as it traverses entire tree structure for each keyword user types. This also just works for exactly matched text : <code>searchText.toLowerCase() === childNode.label.toLowerCase()</code> . Have tried using <code>contains</code> instead of <code>===</code> with no success.</p>

<p>plnkr src : </p>

<pre><code>app.css (removed due to stackoverflow 30000 character limitation when asking questions) 

directives.js (removed due to stackoverflow 30000 character limitation when asking questions) 

filter.js : 

'use strict';

angular.module('app.filters', []);

index.html : 


&lt;!doctype html&gt;
&lt;html lang="en" ng-app="app"&gt;
&lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;title&gt;treeRepeat demo&lt;/title&gt;
  &lt;link rel="stylesheet" href="app.css"/&gt;
&lt;/head&gt;

&lt;body&gt;

  &lt;h1&gt;treeRepeat&lt;/h1&gt;
  &lt;div id="menu" ng-controller="MenuCtrl"&gt;
      &lt;ul&gt;
          &lt;li ng-repeat="item in menu" ng-class="{selected: item == getCurrentMenuItem()}"&gt;&lt;a href="#/{{item.index}}"&gt;{{item.shortLabel}}&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;h2&gt;{{getCurrentMenuItem().fullLabel}}&lt;/h2&gt;
  &lt;/div&gt;

  &lt;ng-view&gt;&lt;/ng-view&gt;

  &lt;script src="angular.js"&gt;&lt;/script&gt;
  &lt;script src="angular-route.js"&gt;&lt;/script&gt;
  &lt;script src="app.js"&gt;&lt;/script&gt;
  &lt;script src="services.js"&gt;&lt;/script&gt;
  &lt;script src="controllers.js"&gt;&lt;/script&gt;
  &lt;script src="filters.js"&gt;&lt;/script&gt;
  &lt;script src="directives.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

services.js : 

'use strict';

angular.module('app.services', [])
    .constant('menu', []);

treerepeat.html : 

&lt;p id="expand-collapse-all"&gt;
    &lt;a href="" ng-click="expandAll()"&gt;Expand all&lt;/a&gt;
    &lt;a href="" ng-click="collapseAll()"&gt;Collapse all&lt;/a&gt;
&lt;/p&gt;


Filter : &lt;input ng-model="myFilter" type="text"&gt;

&lt;ul frang-tree&gt;
  &lt;li frang-tree-repeat="node in treeData | filter:myFilter"&gt;
      &lt;div&gt;&lt;span class="icon"
                 ng-class="{collapsed: node.collapsed, expanded: !node.collapsed}"
                 ng-show="node.children &amp;&amp; node.children.length &gt; 0"
                 ng-click="node.collapsed = !node.collapsed"&gt;&lt;/span&gt;
           &lt;span class="label"
                 ng-class="{folder: node.children &amp;&amp; node.children.length &gt; 0}"
                 ng-bind="node.label"
                 ng-click="action(node)"&gt;&lt;/span&gt;
      &lt;/div&gt;
      &lt;ul ng-if="!node.collapsed &amp;&amp; node.children &amp;&amp; node.children.length &gt; 0"
          frang-tree-insert-children="node.children  | filter:myFilter"&gt;&lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</code></pre>