[angularjs] Angular.js How to change an elements css class on click and to remove all others

i'm trying to make my two elements toggle, so if one element is clicked it will remove all references of my-class and apply it to its self. Any ideas?

<span id="1" ng-style="my-class" ng-click="tog=my-class"></span>

<span id="2" ng-style="my-class" ng-click="tog=my-class"></span>

Cheers!

This question is related to angularjs

The answer is


have you tried with a condition in ng-class like here : http://jsfiddle.net/DotDotDot/zvLvg/ ?

    <span id='1' ng-class='{"myclass":tog==1}' ng-click='tog=1'>span 1</span>
    <span id='2' ng-class='{"myclass":tog==2}' ng-click='tog=2'>span 2</span>

I only change/remove the class:

   function removeClass() {
                    var element = angular.element('#nameInput');
          element.removeClass('nameClass');
   };

To me it seems like the best solution is to use a directive; there's no need for the controller to know that the view is being updated.

Javascript:

var app = angular.module('app', ['directives']);

angular.module('directives', []).directive('toggleClass', function () {
    var directiveDefinitionObject = {
        restrict: 'A',
        template: '<span ng-click="localFunction()" ng-class="selected"  ng-transclude></span>',
        replace: true,
        scope: {
            model: '='
        },
        transclude: true,
        link: function (scope, element, attrs) {
            scope.localFunction = function () {
                scope.model.value = scope.$id;
            };
            scope.$watch('model.value', function () {
                // Is this set to my scope?
                if (scope.model.value === scope.$id) {
                    scope.selected = "active";
                } else {
                    // nope
                    scope.selected = '';
                }
            });
        }
    };
    return directiveDefinitionObject;
});

HTML:

<div ng-app="app" ng-init="model = { value: 'dsf'}"> <span>Click a span... then click another</span>

<br/>
<br/>
<span toggle-class model="model">span1</span>

<br/><span toggle-class model="model">span2</span>

<br/><span toggle-class model="model">span3</span>

CSS:

.active {
     color:red;
 }

I have a fiddle that demonstrates. The idea is when a directive is clicked, a function is called on the directive that sets a variable to the current scope id. Then each directive also watches the same value. If the scope ID's match, then the current element is set to be active using ng-class.

The reason to use directives, is that you no longer are dependent on a controller. In fact I don't have a controller at all (I do define a variable in the view named "model"). You can then reuse this directive anywhere in your project, not just on one controller.


Typically with Angular you would be outputting these spans using the ngRepeat directive and (like in your case) each item would have an id. I know this is not true for all situations but it is typical if requesting data from a backend - objects in an array tend to have unique identifiers.

You can use this id to facilitate the toggling of classes on items in your list (see plunkr or code below).

Using the objects id's can also eliminate the undesirable effect when the $index (described in other answers) is messed up due to sorting in Angular.

Example Plunkr: http://plnkr.co/edit/na0gUec6cdMABK9L6drV

(basically apply the .active-selection class if the person.id is equal to $scope.activeClass - which we set when the user clicks an item.

Hope this helps someone, I've found expressions in ng-class to be very useful!

HTML

<ul>
  <li ng-repeat="person in people" 
  data-ng-class="{'active-selection': person.id == activeClass}">
    <a data-ng-click="selectPerson(person.id)">
      {{person.name}}
    </a>
  </li>
</ul>

JS

app.controller('MainCtrl', function($scope) {
  $scope.people = [{
    id: "1",
    name: "John",
  }, {
    id: "2",
    name: "Lucy"
  }, {
    id: "3",
    name: "Mark"
  }, {
    id: "4",
    name: "Sam"
  }];

  $scope.selectPerson = function(id) {
    $scope.activeClass = id;
    console.log(id);
  };
});    

CSS:

.active-selection {
  background-color: #eee;
}

HTML

<span ng-class="{'item-text-wrap':viewMore}" ng-click="viewMore= !viewMore"></span>