0

I have a ngRepeat function to print some divs which the first one has the active class by default and on div click I want to set the div clicked active and the other ones with the inactive class and I have the next code but I don't know why is not working.

In my controller

$scope.activeSection = 0;

In my view

<div ng-repeat="div in divs" ng-class="activeSection == $index ? 'active' : 'inactive'" ng-click="activeSection = $index">
    <p>Lorem......</p>
</div>

The problem here is when I do click, the div clicked becomes active but is not changing the last activated div to inactive and keeps the active class instead.

Hope you can help me.

SoldierCorp
  • 7,610
  • 16
  • 60
  • 100

2 Answers2

1

The reason being, ngRepeat will create its own $scope - so you're not actually updating the activeSection you think you are - you're creating another variable called activeSection on the ngRepeat scope (child). One way around this is to use $parent (ugly) - or just call a function on your controller to ensure the right $scope is reached:

$scope.setActive = function(index) {
    $scope.activeSection = index;
}

View:

<div ng-repeat="div in divs" ng-class="activeSection == $index ? 'active' : 'inactive'" ng-click="setActive($index)">
    <p>Lorem......</p>
</div>

Definitely read this post regarding $scope and inheritance: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

Community
  • 1
  • 1
tymeJV
  • 103,943
  • 14
  • 161
  • 157
1

ng-repeat defines its own scope. So when activeSection = $index, what is set the the ng-repeat's activeSection variable. Not the controller's activeSection variable.

To solve the problem, define an object in the controller scope:

$scope.sectionModel = {}

And in the view, use

ng-class="sectionModel.activeSection == $index ? 'active' : 'inactive'" ng-click="sectionModel.activeSection = $index"

Or use a function in the controller scope to change the value of activeSection.

BTW, instead of saving the index of the active section, I would store the active section itself. This makes sure that your ng-repeat would work fine even if it uses a filter that changes the number of the order of the sections:

$scope.activeSection = null; // or $scope.div[0] for example
$scope.setActiveSection = function(section) {
    $scope.activeSection = section;
}

<div ng-repeat="div in divs | orderBy:'title'" ng-class="activeSection === div ? 'active' : 'inactive'" ng-click="setActiveSection(div)">
    <p>Lorem......</p>
</div>
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255