Mad-D
Mad-D

Reputation: 4669

AngularJS Accordion is-open check with ng repeat

I am able to make it work without ng-repeat, However when i have list of elements is-Open is not working.
1. I should be able to open one panel at a time( sometimes it opens all )
2. is-Open should get value true upon panel open
3. If user clicks on list of panel contents after opening the panel, i should be able to fetch value ( similar to is-Open on panel ).

html

<body ng-app="myApp">
        <div class="col-sm-6" ng-controller="Controller">
            <div class="column-nav">
                <uib-accordion close-others="oneAtATime">
                    <uib-accordion-group  ng-repeat="group in groups" ng-scroll="group in groups" is-open="$parent.isOpen">
                        <uib-accordion-heading ng-model="checkTitle">
                            {{group.title}}
                        </uib-accordion-heading>
                            <a>{{group.content}}</a>
                    </uib-accordion-group>
                </uib-accordion>
            </div>
            <div>
                Panel Header Open: {{isOpen}} <br>
                Panel oneAtATime: {{oneAtATime}}
            </div>
        </div>  
    </body>

app.js

myApp.controller('Controller', ['$scope', function($scope) {

    $scope.isOpen = false;
    $scope.oneAtATime = true;

    // Data 
     $scope.groups = [
    {
      title: "Dynamic Group Header - 1",
      content: "Content - 1"
    },
    {
      title: "Dynamic Group Header - 2",
      content: "Content - 2"
    }
  ];

  //log
  $scope.$watch('isOpen', function(){
        console.log(" watch isOpen:" +$scope.isOpen);
   }, true);

  }]);

Plunker

Thanks for your help and suggestions.

Upvotes: 4

Views: 11253

Answers (4)

Vikas Bansal
Vikas Bansal

Reputation: 11770

I know its quite late to answer this question but I have a very simple solution that may help the forth visiters

Here it is:

<div ng-if="$parent.isOpen" ng-cloak>

Thanks all and if you want to remove the ng-if once the content is rendered so that you can save some processing then use ::

<div ng-if="::$parent.isOpen" ng-cloak>

Upvotes: 0

ippi
ippi

Reputation: 10167

This is just a slight variation of the other answers. (I'm still unsure about your third requirement, or what you mean by it at least.)

We change this:

...is-open="$parent.isOpen">

Into this (no need to change any data):

...is-open="group.isOpen" ng-click="updateOpenStatus()">

And add the function to the controller, to set a "global" open status. (requirement 2)

$scope.updateOpenStatus = function(){
  $scope.isOpen = $scope.groups.some(function(item){
    return item.isOpen;
  });
}

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

Upvotes: 4

dpaul1994
dpaul1994

Reputation: 320

Try this:

$scope.groups = [
    {
      title: "Dynamic Group Header - 1",
      content: "Content - 1",
      isOpen: false
    },
    {
      title: "Dynamic Group Header - 2",
      content: "Content - 2"
      isOpen: false
    }

With:

Panel Header Open: {{group.isOpen}} <br>

I assume each group has to contains its own properties.

UPDATE

I check it on plunker and it works like this:

 $scope.groups = [
    {
      isOpen: false,
      title: "Dynamic Group Header - 1",
      content: "Content - 1"
    },
    {
      isOpen: false,
      title: "Dynamic Group Header - 2",
      content: "Content - 2"
    }

AND

<uib-accordion-group  ng-repeat="group in groups" ng-scroll="group in groups" is-open="group.isOpen">

And remove $scope.isOpen from js

Upvotes: 0

Paresh Gami
Paresh Gami

Reputation: 4792

Give unique ng-model to each accordion then it will work for you

<uib-accordion-group  ng-repeat="group in groups" ng-scroll="group in groups">
    <uib-accordion-heading ng-model="checkTitle$index">
        {{group.title}}
    </uib-accordion-heading>
    <a>{{group.content}}</a>
</uib-accordion-group>

Upvotes: 0

Related Questions