Change class of just one element in an ngRepeat

10,226

Solution 1

Continuing from the comments. Than you can't use $scope variable for that, because, as you said, it will be the same. TO solve this you need to use ng-class properly. Docs: https://docs.angularjs.org/api/ng/directive/ngClass (see an example at the bottom of the page)

<button ng-class="{'btn-on' : tube.toggled, 'btn-off' : !tube.toggled}" ng-repeat="tube in node.Tubes" ng-click="toggleBtn(tube)">{{"Tube " + ($index + 1)}}</button>

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

Solution 2

I'm not sure I understand if that's what you want, but you can use:

<button class="btn" ng-repeat="tube in node.Tubes" ng-class="{'btn-off':!toggled, 'btn-on':toggled}" ng-click="toggled = !toggled">{{"Tube " + ($index + 1)}}</button>

no need to add any code to the controller in this case.

Solution 3

These other answers are excellent. However, I would like to point out another method for this. Let's say you were looping through an array of receipts. For example, in the controller you had receipts in scope:

$scope.receipts = [ ... ];

And on the front-end you were looping through these receipts:

<div ng-repeat="receipt in receipts">{{ receipt.[attribute] }}</div>

One way to keep track of unique classes is to add a "class" key to the receipt objects. For example a receipt would look like:

receipt { 'id': '1', 'class' : ' ... ' }

On the front-end, you would determine the class using ng-class:

<div ng-repeat="receipt in receipts">
     <div ng-class="receipt.class"></div>
</div>

And then, you could pass the receipt and its ID to a toggleButton() method like so:

<div ng-repeat="receipt in receipts">
     <div class="btn" ng-click="toggleClass(receipt.id)"></div>
     <div ng-class="receipt.class"></div>
</div>

And then within the controller you could simply update the class for that particular receipt (assuming here there is a method getReceipt() that gets a receipt from the array $scope.receipts):

$scope.toggleClass = function(id) {
     getReceipt(id).class = { ... }
}

This would dynamically change the class for that single receipt based on the logic within the toggleClass() function.

Share:
10,226
Jon Harding
Author by

Jon Harding

Web Developer. Interested in AngularJS as well as WebAPI right now

Updated on June 06, 2022

Comments

  • Jon Harding
    Jon Harding about 2 years

    I have an ng-repeat. And I would like to change the class of just that element vs the entire group.

    <button ng-class="defaultClass" ng-repeat="tube in node.Tubes" ng-click="toggleBtn(tube)">{{"Tube " + ($index + 1)}}</button>
    

    with the above HTML on my ng-click I can pass the tube, which really only gives me the data passed from the API, if I console.log(this) I see the class name in an element called $$watchers but that seems odd to change it from there.

    $scope.toggleBtn = function (element) {
        console.log(element);
        console.log(this);
    }
    

    In my controller I have $scope.defaultClass = "btn btn-off"; but if I change that with the function it changes every element.

    How can I only change the class of the element clicked?