1

HTML

<div style="float:left" data-ng-repeat="x in tokens" ng-init="btnclass=false">
                <button type="button" ng-class="{true:'btn btn-material-light-green btn-sm', false:'btn btn-material-grey btn-sm'}[btnclass]" ng-click="toggle($index)">{{x}}</button>
                </div>

Controller file

 $scope.toggle = function(i){
    console.log("done"+i+" ",$scope.btnclass);              
    $scope.btnclass=$scope.btnclass?false:true;
    console.log($scope.btnclass);
}

Console output indicates the variable btnclass does change but I see no effect on the color of button after clicking it.

"done3 " true 
false 
"done3 " false 
true

EDIT Since, alot of people have been questioning the syntax for ng-class expression, I wanted to clarify that this is an old syntax and it works. Refer this question.

Community
  • 1
  • 1
arbazkhan002
  • 1,283
  • 2
  • 13
  • 18

5 Answers5

1

your ng-class is backwards i think. ng-class="{'className': bool}

Also, you don't want to use true and false to apply the class, you want to use the model value that has the value, btnClass

Sam Jacobs
  • 346
  • 1
  • 8
  • I also wouldn't use ng-init, i would just initialize `$scope.btnClass` in the controller – Sam Jacobs Apr 10 '15 at 20:53
  • Agreed, I just made things simple to focus on the problem in hand. My initialization actually is dependent on $index and in the actual code I have used a function there. – arbazkhan002 Apr 10 '15 at 21:47
1

According to ngClass's documentation you're using that expression wrong. If you're using the object syntax, then your keys are supposed to be the class name and the value is supposed to be the expression like this:

ng-class="{'btn btn-material-light-green btn-sm': btnclass, 'btn btn-material-grey btn-sm': !btnclass}"
arjabbar
  • 6,044
  • 4
  • 30
  • 46
0

you could use the ternary operator:

ng-class="btnclass ? 'btn-material-light-green': 'btn-material-grey'"

Also, you don't need to use ng-init="btnclass=false" in the div. btnclass will be false.

since all your buttons are bound to the same btnclass variable, the style on all buttons will change if the value of btnclass is changed.

Saharsh
  • 750
  • 7
  • 18
  • With the ng-repeat each button's parent ends up getting its own scope and btnclass value, so they *can* be colored independently. – Danny Apr 10 '15 at 21:40
0

You have the expression backwards, but you also have a scope problem. You are passing in the index of the ng-repeater, but when the code in toggle hits

$scope.btnclass=$scope.btnclass?false:true;

the first time, it sets a new controller-scope btnclass value to true, and does nothing to the value for the button that called it. The next time you hit any of the buttons, it just changes the "global" btnclass to false. The value for each button never changes.

Depending on what your tokens object looks like, you may want to track the btnclass setting within that object.

I added the properties label and btnclass to the tokens object, so you could pass their object to the toggle function:

<div style="float:left" data-ng-repeat="x in tokens">
  <button type="button" class="btn btn-sm" ng-class="{'btn-material-light-green': x.highlight, 'btn-material-grey': !x.highlight}" ng-click="toggle(x)">{{ x.label }}</button>
</div>

I created an updated Plunker demo here.

Danny
  • 1,740
  • 3
  • 22
  • 32
  • *Yeah that works but not if I put the statement in a function `toggle`, it doesn't work as it should. And yes, I need to do something more than just toggle the class on each click. I guess there's a problem in how the scope is getting resolved. – arbazkhan002 Apr 10 '15 at 21:48
0

The basic functionality demanded could be solved by Danny's answer, but for a requirement more than just toggling the class (which was so in my case), I ended up solving it with the following codeset:

HTML

<div style="float:left" data-ng-repeat="x in tokens" ng-init="btnclass=false">
                <button type="button" ng-class="{true:'btn btn-material-light-green btn-sm', false:'btn btn-material-grey btn-sm'}[btnclass]" ng-click="btnclass=toggle($index)">{{x}}</button>
                </div>

Controller file

 $scope.toggle = function(btnclassVar,i){
    console.log("done"+i+" ",$scope.btnclass);
    //do here what you need to do with argument 'i'
    //...
    return !btnclassVar;
}

I am still not sure why the posted question didn't work while an inline version of it works (some problem in scope resolution maybe?), but this trick worked for me.

Community
  • 1
  • 1
arbazkhan002
  • 1,283
  • 2
  • 13
  • 18