1

I'm trying to apply a class to only one element at a time (see this plunk).

HTML:

<ul>
  <li ng-repeat="item in listItems">
    <a ng-class="{'userActive': isActive, 'userInactive': !isActive}" ng-click="isActive = !isActive">L</a>
    <a ng-class="{'userActive': isActive, 'userInactive': !isActive}" ng-click="isActive = !isActive">R</a>
    <a ng-class="{'userActive': isActive, 'userInactive': !isActive}" ng-click="isActive = !isActive">J</a>
  </li>
</ul>

JS:

var app = angular.module("testApp", []);

app.controller("MainController", function($scope) {
  $scope.listItems = [{description: 'item1', number: 1}];
});

Right now, when I click an element in this list, the class toggle is applied to all elements.

I want to be able to click and unclick each letter to toggle the class change individually. How can I do this?

3 Answers 3

4

The difficulty is that in your case all list elements share the same scope, so when you set isActive there is no way to distinguish which one is actually should be active.

The simple solution to me is to isolate scope for every item. Maybe this is not nicest solution, but pretty simple with the help of very tiny directive:

    <ul>
        <li ng-repeat="item in listItems">
            <a isolate ng-class="{'userActive': isActive, 'userInactive': !isActive}" ng-click="isActive = !isActive">L</a>
            <a isolate ng-class="{'userActive': isActive, 'userInactive': !isActive}" ng-click="isActive = !isActive">R</a>
            <a isolate ng-class="{'userActive': isActive, 'userInactive': !isActive}" ng-click="isActive = !isActive">J</a>
        </li>
    </ul>

Where isolate directive is defined as:

app.directive('isolate', function() {
    return {scope: true};
});
Sign up to request clarification or add additional context in comments.

1 Comment

plus1 way to go @dfsq
1

you need to use three varaibles for ng-class, using one will reflect everywhere

<a ng-class="{'userActive': isActiveL, 'userInactive': !isActiveL}" ng-click="isActiveL = !isActiveL">L</a>
<a ng-class="{'userActive': isActiveR, 'userInactive': !isActiveR}" ng-click="isActiveR = !isActiveR">R</a>
<a ng-class="{'userActive': isActiveJ, 'userInactive': !isActiveJ}" ng-click="isActiveJ = !isActiveJ">J</a>

if you want to use only one varaible

<a ng-class="{'userActive': isActive==1, 'userInactive': isActive!=1}" ng-click="isActive=1">L</a>
<a ng-class="{'userActive': isActive==2, 'userInactive': isActive!=2}" ng-click="isActive=2">R</a>
<a ng-class="{'userActive': isActive==3, 'userInactive': isActive!=3}" ng-click="isActive=3">J</a>

2 Comments

there must be a better way... Consider that I might not know how many users my app will have or how many L, R and J variables I'll need. I can fall back on that solution in a pinch but I'd rather design it with more extensibility.
@amoeboar see updated answer, you can use one variable but youwill need to keep check for 1,2,3 in every case
1

Maybe this:

<ul>
    <li ng-repeat="item in listItems">
        <a ng-class="item.isActive ? 'userActive' : 'userInactive'" ng-click="item.isActive = !item.isActive">{{item.name}}</a>
    </li>
</ul>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.