<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
  <meta charset="utf-8">
  <title>Bootstrap Table Directive</title>
  <link
    rel="stylesheet"
    href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-combined.min.css"
  >
  <link rel="stylesheet" href="style.css">
</head>  
<body ng-controller="Ctrl">
  <h1>Bootstrap Context Menu</h1>
  <p>
    The following table contains the <b>context menu</b> directive,
    which offers the ability to open up a dropdown menu in case of a 
    click on the table row. The directive is bound via <b>context="targetUL"</b>
    and references the <b>ul</b> defined in the document. All click events are
    catched, in case on a document click, the context menu is closed.
  </p>
  <p>
    The scope is applied to the context menu, and the model
    is passed through via scope : '@&', so all click events are passed
    through to the parent controller. That makes the context menu really
    easy to use and the events easy to catch.
  </p>
  <table class="table table-bordered table-striped cell-highlight" style="margin-top: 20px">
    <thead>
      <tr>
        <th>Header One</th>
        <th>Header Two</th>
      </tr>
    </thead>  
    <tbody>
      <tr context="context1">
        <td>Item three</td>
        <td>Item four</td>
      </tr>
      <tr context="context2">
        <td>Item five</td>
        <td>Item six</td>
      </tr>
    </tbody>
  </table>      
  <ul id="context1" class="dropdown-menu">
    <li><a ng-click="edit()">Edit</a></li>
    <li><a ng-click="link()">Link</a></li>
    <li><a ng-click="delete()">Delete</a></li>
    <li class="divider"></li>
    <li><a ng-click="properties()">Properties</a></li>
  </ul>
  <ul id="context2" class="dropdown-menu">
    <li><a ng-click="edit()">Edit</a></li>
    <li class="divider"></li>
    <li><a ng-click="properties()">Properties</a></li>
  </ul>
  <pre>clicked = {{clicked || json }}</pre>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
  <script src="app.js"></script>
  <script src="controller.js"></script>
</body>
</html>
var app = angular.module('myApp', ['directive.contextMenu']);
app.controller('Ctrl', ["$scope", function($scope){
  $scope.clicked = '';
  $scope.edit = function(){
    $scope.clicked = 'edit was clicked';
    console.log($scope.clicked);
  };
  $scope.properties = function(){
    $scope.clicked = 'properties was clicked';
    console.log($scope.clicked);
  };
  $scope.link = function(){
    $scope.clicked = 'link was clicked';
    console.log($scope.clicked);
  };
  $scope.delete = function(){
    $scope.clicked = 'delete was clicked';
    console.log($scope.clicked);
  };
}]);
(function(angular) {
  var directiveContextMenu = angular.module('directive.contextMenu', []);
  directiveContextMenu.directive('cellHighlight', function(){
    var postLink = function(scope, iElement, iAttrs) {
      var td = iElement.find('td');
      td.mouseover(function() {
        $(this).parent('tr').css('opacity', '0.7');
      });
      td.mouseout(function() {
        $(this).parent('tr').css('opacity', '1.0');
      });
    };
    return {
      restrict: 'C',
      postLink: postLink
    };
  });
  directiveContextMenu.directive('context', function() {
    return {
      restrict    : 'A',
      scope       : '@&',
      compile: function compile(tElement, tAttrs, transclude) {
        return {
          post: function postLink(scope, iElement, iAttrs, controller) {
            var ul = $('#' + iAttrs.context);
            var last = null;
            ul.css({ 'display' : 'none'});
            $(iElement).click(function(event) {
              var X = event.clientX;
              var Y = event.clientY;
              ul.css({
                display:  "block",
                position: "fixed",
                top:      Y + 'px',
                left:     X + 'px'
              });
              last = event.timeStamp;
            });
            $(document).click(function(event) {
              var target = $(event.target);
              if(!target.is(".popover") && !target.parents().is(".popover")) {
                if(last === event.timeStamp)
                  return;  
                ul.css({
                  'display' : 'none'
                });
              }
            });
          }
        };
      }
    };
  });
})(window.angular);
.cell-highlight > tbody > tr:hover {
  -webkit-transition: opacity 0.15s linear;
  -moz-transition: opacity 0.15s linear;
  -o-transition: opacity 0.15s linear;
  transition: opacity 0.15s linear;
  opacity: 0.5;
}