[javascript] Expand and collapse with angular js

I am trying to figure out a way to do an expand and collapse using angular js. I haven't been able to find an elegant way to do this without manipulating dom objects in the controller (which is not the angular way). Currently I have a nice way to do it for a one layer expand and collapse. However when I start nesting, things get complicated and don't work the way I want it to (expanding and collapsing multiple areas when they shouldn't be). The problem comes in by me not knowing how to send a unique identifier with an ng-click to only expand/collapse the right content. I should mention that these items are in an ng-repeat so I can necessarily customize parameters being sent.

I was able to use this jsfiddle to help me get a one layer expand and collapse to work. However this is a toggle way to do it and I want the user to be able to keep things expanded while expanding others. So what I did to fix this was use an array of and every time something is clicked the index of that clicked item would be added to the array and the class expanded. When the user clicked again the index was removed from the array and the area was collapsed.

Another way I found that you can do it is by using directives. But I can't really find any exampled to wrap my head around how directives work. I am not sure how to even start when it comes to writing directives.

My current set up is this:

function Dexspander($scope) {
    $scope.ExpandArray = [];

    //Push or pop necessary elements for tracking
    $scope.DespopulatArray = function (identifier, element) {
    if (_.indexOf($scope.ExpandArray, identifier + element) != -1) {
            $scope.ExpandArray.splice(_.indexOf($scope.ExpandArray, identifier + element), 1);
        } else {
            $scope.ExpandArray.push(identifier + element);
        }
    }

    //Change class of necessary elements
    $scope.Dexspand = function (identifier, element) {
        if (_.indexOf($scope.ExpandArray, identifier + element) != -1) {
            return "expand";
        } else {
            return "collapse";
        }
    }
}

<div class="user-header" ng-repeat="user in users">
    <h1 ng-click="DespopulatArray('user', $index)">Expand</h1>
</div>
<div class="user-content" ng:class="Dexspand('user', $index)">
    <div class="content">
        <div class="user-information">
            <div class="info-header">
                <h1 ng-click="DespopulatArray('info', $index)>Some Information</h1>
            </div>
            <div class="info-contents" ng:class="Dexspand('info', $index)">
                stuff stuff stuff stuff...
            </div>
        </div>
    </div>
</div>

The issue with this setup is that if I have to parent divs expanded and those both have something under them to expand, clicking the expand text will expand them in both areas as they are not unique.

This question is related to javascript expand collapse angularjs

The answer is


See http://angular-ui.github.io/bootstrap/#/collapse

function CollapseDemoCtrl($scope) {
  $scope.isCollapsed = false;
}



<div ng-controller="CollapseDemoCtrl">
    <button class="btn" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
    <hr>
    <div collapse="isCollapsed">
        <div class="well well-large">Some content</div> 
    </div>
</div>

I just wrote a simple zippy/collapsable using Angular using ng-show, ng-click and ng-init. Its implemented to one level but can be expanded to multiple levels easily.

Assign a boolean variable to ng-show and toggle it on click of header.

Check it out here enter image description here


Here a simple and easy solution on Angular JS using ng-repeat that might help.

_x000D_
_x000D_
var app = angular.module('myapp', []);_x000D_
_x000D_
app.controller('MainCtrl', function($scope) {_x000D_
_x000D_
  $scope.arr= [_x000D_
    {name:"Head1",desc:"Head1Desc"},_x000D_
    {name:"Head2",desc:"Head2Desc"},_x000D_
    {name:"Head3",desc:"Head3Desc"},_x000D_
    {name:"Head4",desc:"Head4Desc"}_x000D_
    ];_x000D_
    _x000D_
    $scope.collapseIt = function(id){_x000D_
      $scope.collapseId = ($scope.collapseId==id)?-1:id;_x000D_
    }_x000D_
});
_x000D_
/* Put your css in here */_x000D_
li {_x000D_
  list-style:none;_x000D_
  padding:5px;_x000D_
  color:red;_x000D_
}_x000D_
div{_x000D_
  padding:10px;_x000D_
  background:#ddd;_x000D_
}
_x000D_
<!DOCTYPE html>_x000D_
<html ng-app="myapp">_x000D_
  <head>_x000D_
    <meta charset="utf-8" />_x000D_
    <title>AngularJS Simple Collapse</title>_x000D_
    <script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>_x000D_
</head>_x000D_
<body ng-controller="MainCtrl">_x000D_
<ul>_x000D_
  <li ng-repeat='ret in arr track by $index'>_x000D_
    <div ng-click="collapseIt($index)">{{ret.name}}</div>_x000D_
    <div ng-if="collapseId==$index">_x000D_
      {{ret.desc}}_x000D_
    </div>_x000D_
  </li>_x000D_
</ul>_x000D_
</body>_x000D_
</html>
_x000D_
_x000D_
_x000D_

This should fulfill your requirements. Here is a working code.

Plunkr Link http://plnkr.co/edit/n5DZxluYHi8FI3OmzFq2?p=preview

Github: https://github.com/deepakkoirala/SimpleAngularCollapse


You can solve this fully in the html:

<div>
  <input ng-model=collapse type=checkbox>Title
  <div ng-show=collapse>
     Only shown when checkbox is clicked
  </div>
</div>

This also works well with ng-repeat since it will create a local scope for each member.

<table>
  <tbody ng-repeat='m in members'>
    <tr>
       <td><input type=checkbox ng-model=collapse></td>
       <td>{{m.title}}</td>
    </tr>
    <tr ng-show=collapse>
      <td> </td>
      <td>{{ m.content }}</td>
    </tr>
  </tbody>
</table>

Be aware that even though a repeat has its own scope, initially it will inherit the value from collapse from super scopes. This allows you to set the initial value in one place but it can be surprising.

You can of course restyle the checkbox. See http://jsfiddle.net/azD5m/5/

Updated fiddle: http://jsfiddle.net/azD5m/374/ Original fiddle used closing </input> tags to add the HTML text label instead of using <label> tags.


In html

button ng-click="myMethod()">Videos</button>

In angular

 $scope.myMethod = function () {
         $(".collapse").collapse('hide');    //if you want to hide
         $(".collapse").collapse('toggle');  //if you want toggle
         $(".collapse").collapse('show');    //if you want to show
}

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to expand

RecyclerView expand/collapse items Show/Hide Table Rows using Javascript classes Expand and collapse with angular js Apache POI Excel - how to configure columns to be expanded?

Examples related to collapse

Bootstrap 3 - disable navbar collapse Bootstrap Collapse not Collapsing Bootstrap 3 collapse accordion: collapse all works but then cannot expand all while maintaining data-parent Change bootstrap navbar collapse breakpoint without using LESS How to disable margin-collapsing? Collapsing Sidebar with Bootstrap Twitter Bootstrap Use collapse.js on table cells [Almost Done] Expand and collapse with angular js Bootstrap: Collapse other sections when one is expanded

Examples related to angularjs

AngularJs directive not updating another directive's scope ERROR in Cannot find module 'node-sass' CORS: credentials mode is 'include' CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 Print Html template in Angular 2 (ng-print in Angular 2) $http.get(...).success is not a function Angular 1.6.0: "Possibly unhandled rejection" error Find object by its property in array of objects with AngularJS way Error: Cannot invoke an expression whose type lacks a call signature