1

I am creating divs based on ng-repeat. I'm getting the data from a db. The data is like:

[
    {
        id:1,
        name:item1,
        category: [catA, catB, catC,]
    },
    {
        id:2,
        name:item2,
        category: [catB]
    },
    {
        id:3,
        name:item3,
        category: [catA, catB]
    }
]

This data goes in a scope. So:

myApp.controller("myCtrl", function($scope, $http){

    var cat = "catA";

    $http.get("/getdata", function(response){
        if(response.data){
            $scope.items = response.data;

            if(response.data.category==cat){    // Check if the var cat is present in the array. How to do this?
                //set ng-class for the button in the div to 'active'. How to do this?
            }

        } else {
            $scope.message = "Nothing returned.";
        }
    });

    $scope.send = function(n){
        $scope.isActive = !$scope.isActive;
   }
});

I'm using ng-repeat :

<div ng-repeat="item in items" class="myclass">
        {{item.name}}
        <button class="myRight" ng-class="{'active': isActive}" ng-click="send(item.id)"> click </button>
</div>

Active Class:

.active { background: #FF735C; color:white;}

So, based on the var cat present in the array of category received in the data, the class of the button is decided. And if the button is clicked, the class toggles. I cannot use $index for the button to pass the var as if the data is filtered, the proper index is not rendered.

Am I right to use ng-class? Is there any other simpler way to achieve this?

Please help. Many thanks.

4
  • So to confirm, the button should be active if the item has catA as a category and not active once the button is pressed? Commented Mar 16, 2017 at 11:37
  • Yes. Exactly. And if a item does not have catA like item2, the button in this div should be not have the active class. Commented Mar 16, 2017 at 11:41
  • If an active button is clicked, does it then become 'inactive' and is unable to be clicked again? Commented Mar 16, 2017 at 11:49
  • Thanks. No, its just a class. The button is clickable again. Only the class toggles. I added the class in the question. Commented Mar 16, 2017 at 11:52

1 Answer 1

1

Hopefully this should solve your problem, ng-class is definitely the right way to go.

// our store of active buttons/items
$scope.buttonActive = {};

$http.get("/getdata", function(response)
{
    if (response.data)
    {
        angular.forEach(response.data, function (item)
        {
            // create a list of active items based on if it has a category
            $scope.buttonActive[item.id] = item.category.indexOf(cat) !== -1;
        });

        $scope.items = response.data;
    }
    else
    {
        $scope.message = "Nothing returned.";
    }
});

/**
 * @param id
 */
$scope.send = function (id)
{
    // toggle the boolean value for this button/item's state
    $scope.buttonActive[id] = !$scope.buttonActive[id];
}

And in the template:

<div ng-repeat="item in items" class="myclass">
    {{ item.name }}
    <button class="myRight" ng-class="{ 'active': buttonActive[item.id] }" ng-click="send(item.id)">click</button>
</div>

UPDATE

if statements essentially work by evaluating one or more conditions to a boolean value.

if (true)
    doSomething();

So what I'm doing on that line is this:

// if item.categories array contains the category in 'cat' variable
if (item.category.indexOf(cat) !== -1)
    $scope.buttonActive[item.id] = true;
else
    $scope.buttonActive[item.id] = false;

But seeing as I'm assigning a boolean value depending on another boolean value, I may as well just use the result of the initial condition.

var isInArray = item.category.indexOf(cat) !== -1;

$scope.buttonActive[item.id] = isInArray;

Or just:

$scope.buttonActive[item.id] = item.category.indexOf(cat) !== -1;
Sign up to request clarification or add additional context in comments.

1 Comment

What is this magic called? $scope.buttonActive[item.id] = item.category.indexOf(cat) !== -1 Where can I learn more about it?

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.