2

I have a directive that creates a wrapper for an element. The problem with this is the "is-selected" class does not toggle based on the myValue value. I feel like it has something to do with how I'm implementing ng-class with angular element but I'm not sure how to fix this. Any ideas??

Basically I want the wrapping <label> element to have a class based on the the child model value.

    <input my-checkbox type="checkbox" ng-model="myValue" ng-true-value="1" ng-false-value="0">


  module.directive('myCheckbox', function($compile) {
    return {
      restrict: 'A',
      scope: {
        ngModel: '='
      },
      link: function(scope, element) {
        element.attr('type', 'checkbox');
        var wrapperEl = angular.element('<label class="checkbox-label" ng-class="{\'is-selected\': ngModel}"></label>');
        if(scope.ngModel) {
          wrapperEl.addClass('is-selected');
        }
        wrapperEl.on('click', function() {
          // console.log("wrapperEl: %o", wrapperEl);
          var w = angular.element(element[0].parentNode);
          if(scope.ngModel) {
            w.addClass('is-selected');
          } else {
            w.removeClass('is-selected');
          }
        });
        element.wrap(wrapperEl);
        wrapperEl = element.parent();
        var checkEl = angular.element('<i class="Icon Icon--check text-success Icon--lg" ng-show="ngModel"></i>');
        element.attr('style', 'position: absolute; left: -9999px;');
        element.after(checkEl);
        $compile(checkEl)(scope);
      }
    };
  });
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
KingKongFrog
  • 13,946
  • 21
  • 75
  • 124
  • Have you checked out the second answer at http://stackoverflow.com/questions/16928341/update-parent-scope-variable – sova Nov 01 '16 at 20:23
  • Thanks @sova but its slightly unrelated. – KingKongFrog Nov 01 '16 at 20:33
  • you are using `1` and `0` for the values of `ng-model`, but this makes your click no longer operate like a toggle, since both `1 == true` and `0 == true`; your `if(scope.ngModel)` isn't evaluating based on the value, it is evaluating on the *presence* of a value. If you used the default `true` and `false` values for the checkbox, this logic would work. – Claies Nov 01 '16 at 23:38
  • @Claies interesting. How do I circumvent that then? – KingKongFrog Nov 01 '16 at 23:40
  • if you must use `1` and `0`, then changing your statement to `if (scope.ngModel == 1)` should be enough. however, this breaks the moment someone uses the directive without the `ng-true-value` statement. – Claies Nov 01 '16 at 23:42
  • I haven't had time to actually reproduce the code and look at the final output, but I think there should be another way to capture the state of the element. – Claies Nov 01 '16 at 23:47

1 Answers1

0

I fixed this by adding the $watch method.

scope.$watch('ngModel', function() {
  if(scope.ngModel) {
    wrapperEl.addClass('is-selected');
  }
  else
  {
    wrapperEl.removeClass('is-selected');
  }
});
KingKongFrog
  • 13,946
  • 21
  • 75
  • 124