Search code examples
angularjsangularjs-ng-click

Dynamically disable all ng-clicks within an element


I have a directive disable-ng-clicks and under certain conditions, I want to prevent all ng-clicks that are children of the directive. Here is some example markup:

<div disable-ng-clicks> <!-- directive -->
  <a ng-click="someAction()"></a>
  <div ng-controller="myController">
    <a ng-click="anotherAction()"></a>
    <a ng-click="moreActions()"></a>
  </div>
</div>

If these were normal hyperlinks, I could do something like this in the link function:

function(scope, iElement, iAttrs) {
  var ngClicks = angular.element(iElement[0].querySelectorAll('[ng-click]'));
  ngClicks.on('click', function(event) {
    if(trigger) { // a dynamic variable that triggers disabling the clicks
      event.preventDefault();
    }
  });
}

But this does not work for ng-click directives. Is there another way to accomplish this?


Solution

  • Here is the best I could come up with. I created a new directive to replace ng-click:

     directive('myClick', ['$parse', function($parse) {
      return {
        restrict: 'A',
        compile: function($element, attrs) {
          var fn = $parse(attrs.myClick);
          return function (scope, element, attrs) {
            var disabled = false;
            scope.$on('disableClickEvents', function () {
              disabled = true;
            });
            scope.$on('enableClickEvents', function () {
              disabled = false;
            });
            element.on('click', function (event) {
              if (!disabled) {
                scope.$apply(function () {
                  fn(scope, { $event: event });
                });
              }
            });
          };
        }
      }
    }]);
    

    So in a different directive, I can have:

    if (condition) { 
      scope.$broadcast('disableClickEvents');
    }
    

    and when I want to re-enable:

    if (otherCondition) { 
      scope.$broadcast('enableClickEvents');
    }
    

    I don't like having to use a different directive for ng-click, but this is the best plan I could think of.