Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular-ui-bootstrap accordion collapse/expand all

I would like to create a collpase/expand all button for a set of accordions. I am using angular.js v1.2.6 and angular-bootstrap-ui 0.9.0. I haven't been able to find an example of how to do a collpase/expand all. I'm an angular novice and any advice or suggestions is appreciated.

ALSO, I should add that the solution in this post doesn't work in the newer version of angular.js (v1.0.8 vs v1.2.6) that I am using (which is a latest version at the time of this posting). In the newer version it throws an error about trying to create two isolated scopes.

Markup:

    <div ng-controller="myCtlr">

     <accordion close-others="oneAtATime">

     <button class="btn" ng-click="section.isCollapsed = !section.isCollapsed">Toggle Sections</button>

      <accordion-group ng-repeat="section in sections" is-open="section.isOpen">
       <accordion-heading>
        <div class="accordion-heading-content" ng:class="{collapsed: section.isOpen}">
          {{section.name}}
        </div>
       </accordion-heading>
        Section content
      </accordion-group>

     </accordion>

   </div>

JS:

var theapp = angular.module('myApp', [
  'ui.bootstrap'
])

function myCtlr ($scope) {
 $scope.isCollapsed = false;
 $scope.sections = [
    {'id': '353','otherid': '7','name': 'One','Sequence': '1'},
    {'id': '354','otherid': '8','name': 'Two','Sequence': '1'},
    {'id': '355','otherid': '9','name': 'Three','Sequence': '1'}
];

}
like image 626
Konsuela Avatar asked Jan 02 '14 16:01

Konsuela


1 Answers

I've taken Blowsie's plunkr comment and built my own answer that solves the use case that I'm reading into here.

I've moved the close-others attribute to the accordion element where the docs say it goes. I've also added extra buttons to openAll, closeAll or toggleAll.

If you click the header for a single item, only that item opens. If you click a 'All' button, all are affected.

Thanks to Blowsie for the inspiration. I think using the item.open here was the ticket. After that, it's just a matter of affecting all item.open values.

http://plnkr.co/edit/WUKEfcBrSf3XrIQAik67?p=preview

HTML

<div ng-controller="AccordionDemoCtrl">

  <accordion close-others="false">
    <accordion-group ng-repeat="item in items" is-open="item.open" heading="{{item.name}}">
      {{item.open}}
      <p>The body of the accordion group grows to fit the contents</p>
    </accordion-group>
  </accordion>

  <button ng-click="openItem(0)">Open 1</button>
  <button ng-click="openItem(1)">Open 2</button>
  <button ng-click="openItem(2)">Open 3</button>
  <button ng-click="openAllItems()">Open All</button>
  <button ng-click="closeAllItems()">Close All</button>
  <button ng-click="toggleAllItems()">Toggle All</button>
  <br/>

 {{items |json}}
</div>

JS

angular.module('plunker', ['ui.bootstrap']);
function AccordionDemoCtrl($scope) {
  $scope.oneAtATime = true;

  $scope.items = [
    {name: 'Item 1', open: false},
    {name: 'Item 2', open: false},
    {name: 'Item 3', open: false}
  ];

  $scope.addItem = function() {
    var newItemNo = $scope.items.length + 1;
    $scope.items.push('Item ' + newItemNo);
  };


  $scope.openItem = function(idx) {
    console.log(idx);
    $scope.items[idx].open = true; 
  };

  $scope.openAllItems = function(){
    $scope.items.map(function(item){
      item.open = true;
    });
  };

  $scope.closeAllItems = function(){
    $scope.items.map(function(item){
      item.open = false;
    });
  }

  $scope.toggleAllItems = function(){
    $scope.items.map(function(item){
      item.open = !item.open;
    });
  }

}
like image 64
coblr Avatar answered Oct 14 '22 01:10

coblr