Shailesh Bhat
Shailesh Bhat

Reputation: 152

How to close nested ui-bootstrap accordion when parent closes

The Problem posted here(I need to close inner accordion automatically, when I close outer/Parent Accordion) is not answered till now. Can anyone help me to get the solution for the above stated problem please. ..Thank you so much in advance...

"Click here to see the plunker demo"

<div ng-controller="AccordionDemoCtrl"> 
  <accordion close-others="oneAtATime">
    <accordion-group heading="Static Header">
      This content is straight in the template.
    </accordion-group>
    <accordion-group heading="{{group.title}}" ng-repeat="group in groups">
      {{group.content}}
    </accordion-group>
    <accordion-group heading="Nested Accordian">
        <accordion close-others="oneAtATime">
          <accordion-group heading="Static Header">
            This content is straight in the template.
          </accordion-group>
          <accordion-group heading="{{group.title}}" ng-repeat="group in groups">
            {{group.content}}
          </accordion-group>
        </accordion>
    </accordion-group>
  </accordion>

Upvotes: 1

Views: 946

Answers (2)

Marcus H&#246;glund
Marcus H&#246;glund

Reputation: 16811

You could solve this by keeping track of the selected group. In this example I've added a custom html tag called handler (you could add an other, I've just made it up) to wrap the accordion-groups and make sure the handler tags ng-click fire before the directive click event.

First, add these to the scope

$scope.m = {};
  $scope.m.isSelected = '';
  $scope.m.set = function(value){
    $scope.m.isSelected = value; 
  };

Then call the m.set when each handler is clicked

<div ng-controller="AccordionDemoCtrl"> 
  <accordion close-others="oneAtATime">
    <accordion-group heading="Static Header">
      This content is straight in the template.
    </accordion-group>
    <accordion-group heading="{{group.title}}" ng-repeat="group in groups">
      {{group.content}}
    </accordion-group>
    <accordion-group close-others="false">
      <accordion-heading><span ng-click="m.set('none')">Nested Accordian</span></accordion-heading>
        <accordion>
          <handler ng-click="m.set('Static')">
          <accordion-group is-open="m.isSelected == 'Static'">
            <accordion-heading><span >Static Header</span></accordion-heading>
            This content is straight in the template.
          </accordion-group>
          </handler>
          <handler ng-repeat="group in groups" ng-click="m.set(group.title)">
          <accordion-group is-open="m.isSelected == group.title">
           <accordion-heading><span>{{group.title}}</span></accordion-heading>
            {{group.content}}
          </accordion-group>
          </handler>
        </accordion>
    </accordion-group>
  </accordion>
</div>

Plunker here

Upvotes: 1

xelilof
xelilof

Reputation: 456

first add an accordion-heading on the parent instead of the heading attribute so we can add on-click event like this :

 <accordion-group >
        <accordion-heading>
          <span  ng-click='onParentCollapse()'>Nested Accordian</span>
        </accordion-heading>

instead of the old one :

 <accordion-group  heading="Nested Accordian">

then define an object to handle the status of the static child accordions :

  $scope.staticAccordionsFlag = {
    open : false
  };

then alter the groups to have an extra attribute for the dynamic childs :

  $scope.groups = [
    {
      title: "Dynamic Group Header - 1",
      content: "Dynamic Group Body - 1",
      open: false
    },
    {
      title: "Dynamic Group Header - 2",
      content: "Dynamic Group Body - 2",
      open: false
    }
  ];

then define the function onParentCollapse : in the controller

  $scope.onParentCollapse = function(){

   //for the ones dynamicly generated 
   angular.forEach($scope.groups, function(element) {
      element.open = false;
    });

    //for the static ones
    $scope.staticAccordionsFlag.open = false;

  }

finally adjust the child accordions to have the linked dynamic flags to be open or nor :

  <accordion close-others="oneAtATime">
          <accordion-group is-open="staticAccordionsFlag.open" heading="Static Header">
            This content is straight in the template.
          </accordion-group>
          <accordion-group is-open="group.open" heading="{{group.title}}" ng-repeat="group in groups">
            {{group.content}}
          </accordion-group>

if you got lost here is your full code : HTML :

<!doctype html>
<html ng-app="plunker">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
  </head>
  <body>

<div ng-controller="AccordionDemoCtrl"> 
  <accordion close-others="oneAtATime">
    <accordion-group heading="Static Header">
      This content is straight in the template.
    </accordion-group>
    <accordion-group heading="{{group.title}}" ng-repeat="group in groups">
      {{group.content}}
    </accordion-group>
    <accordion-group>
        <accordion-heading>
          <span  ng-click='onParentCollapse()'>Nested Accordian</span>
        </accordion-heading>
        <accordion close-others="oneAtATime">
          <accordion-group is-open="staticAccordionsFlag.open" heading="Static Header">
            This content is straight in the template.
          </accordion-group>
          <accordion-group is-open="group.open" heading="{{group.title}}" ng-repeat="group in groups">
            {{group.content}}
          </accordion-group>
        </accordion>
    </accordion-group>
  </accordion>
</div>

  </body>
</html>

and the JS :

function AccordionDemoCtrl($scope) {
  $scope.oneAtATime = true;

  $scope.groups = [
    {
      title: "Dynamic Group Header - 1",
      content: "Dynamic Group Body - 1",
      open: false
    },
    {
      title: "Dynamic Group Header - 2",
      content: "Dynamic Group Body - 2",
      open: false
    }
  ];



  $scope.staticAccordionsFlag = {
    open : false
  };

  $scope.onParentCollapse = function(){

   //for the ones dynamicly generated 
   angular.forEach($scope.groups, function(element) {
      element.open = false;
    });

    //for the static ones
    $scope.staticAccordionsFlag.open = false;

  }

}

Upvotes: 0

Related Questions