Search code examples
javascriptcssangularjsng-class

ng-class updates all items in ng-repeat in AngularJs view when class is changed


I am trying to apply AngularJs' ng-class only to the specific item that is clicked, but no matter where I put the ng-class="class", each time the class gets updated, it is applied to all items in the ng-repeat directive.

Interesting: I would have thought that adding it with data-target="#collapse_{{ $index }} would only change the corresponding item with the same $index? :(

What am I doing wrong?

How can I have the class change only apply to the specific item that was clicked? I want to create something where a user can select and un-select a line.

Here is a very similar post, but I am not sure how to implement this according to my needs: Only add class to specific ng-repeat in AngularJS

He is my basic HTML for my header I want to change:

<div class="panel-heading">
    <div class="container-fluid panel-container item-container">
        <div class="col-xs-1 text-left">
            <h4>
                <a data-toggle="collapse" data-target="#collapse_{{ $index }}">
                    <span class="glyphicon glyphicon-list"></span>
                </a>
            </h4>
        </div>
        <div class="col-xs-8 text-left product-header">
            <a data-toggle="collapse" data-target="#collapse_{{ $index }}">
                <span>Product Name: {{product.productName}}</span>
            </a>
        </div>
        <div class="col-xs-3 text-right">
            <span class="panel-title btn-group">
                <button type="button" id="button-selected" class="btn btn-default btn-sm abc" ng-click="addProduct(product)" ng-class="class">
                    <span class="glyphicon glyphicon-plus text-primary"></span>
                </button>
            </span>
        </div>
    </div>
</div>

Here is my CSS:

.active-product {
    background: red;
    color: green;
}

.inactive-product {
    background: none;
    color: none;
}

Here is my controller method (it is called by the addProduct function):

$scope.class = "inactive-product";

function changeClass() {
    if ($scope.class === "active-product")
        $scope.class = "inactive-product";
    else
        $scope.class = "active-product";
};

This is an example how every item gets changed:enter image description here


Solution

  • There is only one $scope.class, so it makes sense that every element is using it. You may need one class property on each product:

    Template:

    ng-class="product.class"
    

    Controller:

    function changeClass(product) {
        if (product.class === "active-product")
            product.class = "inactive-product";
        else
            product.class = "active-product";
    };