27

When a class is added to an element, I want to add another class to that element. When a class is removed, I want to remove an element. I'm basically mapping some bootstrap classes to some angular form validation classes but I can't figure out how to fire my code when a class is added/removed from an element (also making sure not to cause some infinite loop of class changing).

Here is what I have thus far for my directive:

.directive('mirrorValidationStates', ['$log', function($log) {
  function link(scope,element,attrs) {
    scope.$watch(element.hasClass('someClass'), function(val) {
      var classMap = {
        'popupOn': 'has-error',
        'ng-valid': 'has-success'
      };

      for (var key in classMap) {
        if (element.hasClass(key)) {
          $log.info("setting class " + classMap[key]);
          element.parent().addClass(classMap[key]);
        } else {
          $log.info("removing class " + classMap[key]);
          element.parent().removeClass(classMap[key]);
        }
      }
    });
  }
  return {
    link: link
  };
}]);

So basically, when popupOn is added to an element, I want to add the has-error bootstrap class to the parent element. When popupOn is removed, I want to remove has-error.

What am I missing to make this happen in Angular? Maybe something with ng-class and not use a directive?

Thanks much!

2 Answers 2

46

works here

You may want to try this construction to follow class changes:

$scope.$watch(function() {return element.attr('class'); }, function(newValue){});

Please notice that adding/removing classes insight that watch will cause one additional call of adding class that wont change class attribute value.

But I think the better approach will be using ng-class. For example in a moment you want to add a 'popupOn' class you are setting some scope value ($scope.popup = true) and then specify ng-class for parent and child element like so:

<div ng-class={'has-error': (popup==true)}>
    <div id="patient" ng-class={'popupOn': (popup==true)}>test</div>
    <button ng-click="addClass()">addClass</button>
    <button ng-click="removeClass()">removeClass</button>
</div>

when you want to remove those classes you just set $scope.popup value to false

Fiddle with ng-class

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks! I don't think I fully comprehended that construction to $watch when I was reading the docs last night. Thanks much.
Take care when using $animated elements. As for angular 1.5 this might not trigger for the animation completed state right away, but only for the 'add'-state.
$ scope.$watch - some people copy and paste!
@AhmadReza in directives scope injection is position based rather than dependency injection like in controllers. So no need $ sign.
May as well just check for truthy instead of using popup == true
-5

I add/remove the class:

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

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

Comments

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.