Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand/Collapse child elements in a tree (AngularJS)

I'm a newbie in AngularJS and faced with an issue.

Need to create message history tree, which provides expand/collapse functionality on the parent item.

I've created view:

<div class="tree">
<ul>
    <li ng-repeat="appt in apptsToFilter() | filter: groupByAppt" ng-click="showChilds()">
        <span>{{appt.startTime}} - Appt. Id: {{appt.appointmentId}} </span>
        <ul>
            <li ng-repeat="item in appts | filter: {appointmentId: appt.appointmentId}" ng-show="active">
                <span>{{item.message}}</span>
            </li>
        </ul>
    </li>
</ul>
</div>

This is my controoler for this view:

function MessageHistoryController($scope, $routeParams, MessageHistoryResource) {
    ......//some code

    $scope.active = false;
    $scope.showChilds = function() {
        if ($scope.active == false) {
            $scope.active = true;
        } else {
            $scope.active = false;
        }
    };
}

This is what I get, when I've expanded first parent item:

ParentItem2:
   - Child1
   - Child2
   - Child3

ParentItem2
   - Child1
   - Child2

ParentItem3
   - Child1

When I click on any parent item - all of my subtrees expanded or collapsed.

But I expected this result, as below (only clicked item should be expanded):

ParentItem2:
   - Child1
   - Child2
   - Child3
ParentItem2
ParentItem3

Any ideas are appreciated. Thanks.

like image 369
Artyom Pranovich Avatar asked Jan 23 '26 11:01

Artyom Pranovich


1 Answers

That's because you have all of your parent, clickable items, set to one boolean. This can be resolved in the HTML without the active bool.

  1. Set your show/hide element to:

    ng-show="appt.active"

  2. Then set your click call to:

    ng-click="appt.active = !appt.active"

Full Example:

<div class="tree">
<ul>
    <li ng-repeat="appt in apptsToFilter() | filter: groupByAppt" ng-click="appt.active = !appt.active">
        <span>{{appt.startTime}} - Appt. Id: {{appt.appointmentId}} </span>
        <ul>
            <li ng-repeat="item in appts | filter: {appointmentId: appt.appointmentId}" ng-show="appt.active">
                <span>{{item.message}}</span>
            </li>
        </ul>
    </li>
</ul>
</div>

Even though appt.active would initialize as undefined when clicked it will change to true, at least it does on my end and this is how I handle these cases.

You could also loop through the appt and define active in the javascript.


For future reference you can simplify your $scope.showChilds function to:

$scope.showChilds = function () {
    $scope.active = !$scope.active
}
like image 118
Jonathan Jones Avatar answered Jan 25 '26 00:01

Jonathan Jones



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!