sydcanem / bootstrap-contextmenu

Context menu plugin for Twitter's Bootstrap framework
http://sydcanem.com/bootstrap-contextmenu/
645 stars 193 forks source link

added inactivity dissapear timer + option #41

Closed timkock closed 10 years ago

timkock commented 10 years ago

I love this repo. One of the things I noticed immediately when implementing with different menu's and multiple items that have a context menu is that menu's don't disappear unless you click somewhere on the page. Now if you are not interacting with a menu it will close itself after a specified or standard duration.

sydcanem commented 10 years ago

How about keeping track of mutliple menus and add behavior to only open 1 menu at a time. Much like your desktop and browser's context menu. They don't open at the same time I believe.

timkock commented 10 years ago

I ended up implementing a different method for Angular. Working in angular, built a custom context menu directive that references a context menu div. I left the option out of tracking the menu's because sometimes two need to be open at the same time. In my case I commented out the setting the selected item (the context menu is applied to an ng-repeat containing element). This way I could bind scope to the item in ng-repeat.

(function (angular) {

  angular.module('ms')
  .directive('context', [function() {
    return {
      restrict: 'A',
      scope: '&@',
      compile: function compile(tElement, tAttrs) {
        return {
          post: function postLink(scope, iElement, iAttrs, controller) {

            var menu = $('#' + iAttrs.context)
              , last = null
              , menuTimer = function() {
                  if (menu.timer) {
                    clearTimeout(menu.timer);
                  }
                  menu.timer = setTimeout(function () {
                    menu.timer = null;
                    if(!menu.live)
                        closeMenu();
                  }, 1000);
                },
                closeMenu = function() {
                  menu.css({ 'display' : 'none' });
                };

            // Set default styles
            menu.css({ 'display' : 'none'});
            menu.addClass('cmenu');

            // Bind to menu mouse operations
            $(menu).bind('mouseenter', function(e) {
              menu.live = true;
            });
            $(menu).bind('mouseleave', function(e) {
              menu.live = false;
            });
            $(menu).bind('mousemove', function(e) {
              menuTimer();
            });

            // Show menu on row context called
            $(iElement).bind('contextmenu', function(event) {
              event.preventDefault();
              //scope.$apply(function() {
                //scope.$parent.selectItem(scope.item);
              //});
              menu.css({
                position: "fixed",
                display: "block",
                left: event.clientX + 'px',
                top:  event.clientY + 'px'
              });
              last = event.timeStamp;
              menuTimer();
            });

            // Remove element on document click outside of element
            $(document).click(function(event) {
              var target = $(event.target);
              if(!target.is(".cmenu") && !target.parents().is(".cmenu")) {
                closeMenu();
                if(last === event.timeStamp)
                  return;
              } else {
                closeMenu();
                event.preventDefault();
              }
            });

            // Prevent contextmenu within the contextmenu
            $(document).bind('contextmenu', function(event) {
              var target = $(event.target);
              if(!target.is(".cmenu") && !target.parents().is(".cmenu")) {
                if(last === event.timeStamp)
                  return;
              } else {
                event.preventDefault();
              }
            });

          }
        };
      }
    };
  }]);

}(window.angular));

And the context menu html (uses fontawesome icons) & bootstrap menu css

  <ul id="pattern-item-context" class="dropdown-menu">
    <li role="presentation" class="dropdown-header"><i class="fa fa-barcode"></i> Menu</li>
    <li><a ng-click="scopeActionOne()"><i class="fa fa-pencil-square-o"></i> Edit</a></li>
    <li role="presentation" class="divider"></li>
    <li><a ng-click="scopeActionTwo()"><i class="fa fa-trash-o"></i> Delete</a></li>
  </ul>
sydcanem commented 10 years ago

Ok. Seems you figured it out yourself. I'm closing this one.