2

I'd like to toggle a class when an element is clicked using AngularJS. I need the clicked element to received the class, and any other items in the list to loose the class. I've researched a number of supposed solutions for this on SO, however in implementing them, they don't work appropriately and I don't understand why they would even.

The general solution proposed is to set a variable to the index of the item in the ng-repeat list. Then use ng-class to add the class. JSFiddle here.

<div ng-app>
<p ng-repeat="item in ['a', 'b', 'c']"
    ng-click="selectedIndex = $index"
    ng-class="{selected: $index === selectedIndex}"    
>{{item}}</p>
</div>

The problem is that the 'selected' class is never removed from the previous elements. So, clicking an element adds the class to the element as expected, but clicking another element doesn't remove the class from previously clicked elements. I would guess because Angular is not re-rendering the entire list on each click and thus the old clicked elements don't change. That begs my question though, why is this such an overwhelmingly proposed solution? Am I just implementing something wrong? Thanks.

0

1 Answer 1

3

That's because ng-repeat creates its own child scope, so your other elements each have their own instance of selectedIndex - create a function so selectedIndex is seen by all repeated elements:

Controller:

$scope.setSelected = function(index) {
    $scope.selectedIndex = index;
}

<div ng-app>
    <p ng-repeat="item in ['a', 'b', 'c']"
        ng-click="setSelected($index)"
        ng-class="{selected: $index === selectedIndex}"    
    >{{item}}</p>
</div>
Sign up to request clarification or add additional context in comments.

3 Comments

Was writing the exact same answer :)) - here's a fiddle of it in action: jsfiddle.net/zqdmm4zt
Works great now, thanks for that. To better understand, why does the class get removed from the other elements? Does Angular rebuild the entire list on each click or does ng-class get re-evaluated on each click?
ng-class will be re-evaluated each $digest cycle - and the $digest cycle is trigger on the click event (and a multitude of other events)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.