Seer
Seer

Reputation: 5237

Angular JS - How to select anything but the given element with jqLite?

I'm currently writing a directive to handle a side menu in a mobile application. I can open the menu just fine with the directive I've created, however I need to be able to select everything but the menu with jqLite so that I can bind a click event to close the menu if anything but the menu is clicked.

My directive is currently:

  .directive('asideMenuButton', [function() {
    return {
      restrict: 'A',
      link: function(scope, $el, attrs) {
        $el.on('click', function(e) {
          e.preventDefault();

          var $aside = angular.element(document.getElementById(attrs.parent));

          if ($aside.hasClass('active')) {
            $aside.removeClass('active');
          } else {
            $aside.addClass('active');
          }
        });
      }
    };
  }]);

The basic usage is the following:

<a aside-menu-button href="#" data-parent="<aside ID>">Link</a>

How can I get any element but the menu in jqLite?

Edit: My final solution was the following:

angular.module('wowpr.directives', [])
  .directive('asideMenuButton', [function() {
    return {
      restrict: 'A',
      link: function(scope, $el, attrs) {
        var $aside = angular.element(document.getElementById(attrs.parent));
        var $body  = angular.element(document.getElementsByTagName('body'));

        $body.on('click', function(e) {
          if ($aside.hasClass('active')) {
            $aside.removeClass('active');
          }
        });

        $aside.on('click', function(e) {
          e.stopPropagation();
        });

        $el.on('click', function(e) {
          e.preventDefault();
          e.stopPropagation();

          if ($aside.hasClass('active')) {
            $aside.removeClass('active');
          } else {
            $aside.addClass('active');
          }
        });
      }
    };
  }]);

It doesn't check in the body click event to see if the element being clicked is the menu, instead when you click on the menu it stops the propagation of the click event travelling to the body. That way it doesn't fire the body click event when you click on the menu.

Upvotes: 1

Views: 1479

Answers (1)

Patrick Evans
Patrick Evans

Reputation: 42736

Bind the click event to the document or body element. Then check that the target element is not part of the menu. If it is not close the menu.

angular.element(document).on("click",function(e){
   if( !angular.element(e.target).hasClass("someMenuClass") ) {
       closeMenu();
   }
});

Upvotes: 4

Related Questions