Reputation: 1222
I'm applying a button to a list-group-item using ng-repeat where the button has a class btn-primary when not selected and a minus glyphico and a class btn-success when selected and an ok glyphicon. I'm trying to apply this conditionally using ng-class which is fine, but how to do it by $index selection I don't know. I've looked at examples using the ternary and logic ( && ) operators but can't seem to get the syntax right. To clarify I'd like one button when clicked to change it's icon and it's colour. As you can see I am successfully using the $index to select a group-item and change its colour no problem.
Here's a plunk
http://plnkr.co/edit/dPoHtL7MgFNX4FhDXoBH?p=preview
<button class="btn btn-sm pull-right move-button" ng-class="{'btn-success': Activatorator, 'btn-primary': !Activatorator}" ng-click="markActive($event, this.$index)">
<span ng-class="{'glyphicon glyphicon-ok': Activatorator, 'glyphicon glyphicon-minus': !Activatorator}"></span>
</button>
***** Solution
I fixed this using the selected ng-repeat item as suggested. Since the regular 'class' on an html element sort of acts like the 'else' clause in an if/else I used that to evaluate the default state of the button, btn-primary with glyphicon-minus and ng-class to change the state on click by id.
Working plunker http://plnkr.co/edit/0j9BxFQdD2lIx7lgthDR?p=preview
Upvotes: 2
Views: 3294
Reputation: 171679
Forget using index and pass the active id
to function :
ng-click="setSelected(id)"
$scope.selected ={ id: null}
$scope.setSelected = function(id) {
$scope.selected.id = id;
}
$scope.selected
is an object so that it will get inherited by the child scopes created in ng-repeat
whereas a primitive won't
Then you can compare the id
of ng-repeat
to selected.id
ng-class="{'list-group-item-info': selected.id == id}"
Upvotes: 2
Reputation: 691625
You're using a single scope variable to store the state of 6 different elements. That can't possibly work.
Forget about using the index. That's a bad idea. For example, as soon as you use an orderBy or filter filter, the index of a given element of the array will change. Same if you implement the remove() function; a given element will have its index modified, but you still want its state to be unchanged.
Instead, iterate over objects, and store the state of the object as an attribute of the object. When you click on a button, you change the state of the current object. As simple as that.
Here's a working version of your plunkr: http://plnkr.co/edit/GxI4AyeGBPTDKDFS8Zjf?p=preview
Key stuff:
$scope.objectsFromServer = [{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
},
{
id: 5
},
{
id: 6
}];
$scope.setSelected = function(object) {
$scope.selectedObject = object
}
$scope.markActive = function(object, $event) {
object.active = !object.active;
$event.stopPropagation();
$event.preventDefault();
};
and
<li ng-repeat="object in objectsFromServer " ng-click="setSelected(object)" class="list-group-item" ng-class="{'list-group-item-info': object == selectedObject}">{{ object.id }}
<button disabled="" class="btn btn-sm btn-danger pull-right move-button" ng-click="remove()">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button class="btn btn-sm pull-right move-button" ng-class="{'btn-success': object.active, 'btn-primary': !object.active}" ng-click="markActive(object, $event)">
<span ng-class="{'glyphicon glyphicon-ok': object.active, 'glyphicon glyphicon-minus': !object.active}"></span>
</button>
</li>
Upvotes: 0
Reputation: 136124
Basically you need to create a method in scope which will give you the value of activated row.
Markup
<button class="btn btn-sm pull-right move-button" ng-class="{'btn-success': isActivate($index), 'btn-primary': !isActivate($index)}" ng-click="markActive($event, this.$index)">
<span ng-class="{'glyphicon glyphicon-ok': isActivate($index), 'glyphicon glyphicon-minus': !isActivate($index)}"></span>
</button>
Code
$scope.setSelected = function(idx) {
$scope.indx = idx;
}
$scope.isActivate =function(idx){
return $scope.indx == idx
}
Though playing with
$index
ofng-repeat
is not an good idea to do, @JB Nizet already given answer for the other way which would be best way to implement it.
Upvotes: 0