Templarian / ui.bootstrap.contextMenu

AngularJS Bootstrap UI Context Menu
MIT License
259 stars 127 forks source link

Can't use with UI-Grid #87

Closed 5im5im closed 8 years ago

5im5im commented 8 years ago

Hi there

ContextMenu works fine, except in UI-Grid. They use an isolated scope so the scope is not that one context menu expect.

What ever UI-Grid provides the original scope via grid.appScope. I could only fix it if I edited the contextMenu JS in the last function which is very dirty to edit a 3rd party libary...

[...]
return function ($scope, element, attrs) {
        // Dirty Patch UI-grid support
        var contextMenuScope = $scope;
        if ($scope.col && $scope.col.grid && $scope.col.grid.appScope) {
            contextMenuScope = $scope.col.grid.appScope;
        }
        //END Patch
[...]

So I can use the original scope and the context menu will be displayed. Has anybody experience with ui.bootstrap.contextMenu under UI-Grid?

thx and kind regards 5im5im

[...]
return function ($scope, element, attrs) {
        // Patched für Unterstützung aus ui-grid.
        var contextMenuScope = $scope;
        if ($scope.col && $scope.col.grid && $scope.col.grid.appScope) {
            contextMenuScope = $scope.col.grid.appScope;
        }
        //END Patch
        var openMenuEvent = "contextmenu";
        if(attrs.contextMenuOn && typeof(attrs.contextMenuOn) === "string"){
            openMenuEvent = attrs.contextMenuOn;
        }
        element.on(openMenuEvent, function (event) {
            if(!attrs.allowEventPropagation) {
              event.stopPropagation();
              event.preventDefault();
            }

            // Don't show context menu if on touch device and element is draggable
            if(isTouchDevice() && element.attr('draggable') === 'true') {
              return false;
            }

            contextMenuScope.$apply(function () {
                var options = contextMenuScope.$eval(attrs.contextMenu);
                var customClass = attrs.contextMenuClass;
                var modelValue = contextMenuScope.$eval(attrs.model);
                if (options instanceof Array) {
                    if (options.length === 0) { return; }
                    renderContextMenu(contextMenuScope, event, options, modelValue, undefined, customClass);
                } else {
                    throw '"' + attrs.contextMenu + '" not an array';
                }
            });
        });
    };
bhochberger commented 8 years ago

Actually i have got a working example without changing contextmenu-Library. I totally agree with you about patching 3rd party libraries. :) Ok, here we go: my npm-versions for completness: angular version 1.4.x angular-ui-grid version 3.2.x angular-bootstrap-contextmenu 0.9.x

Controller part (just snippets):

$scope.gridOptions = { 
   ...
   rowTemplate:  '<div context-menu="grid.appScope.contextmenuOptions()" >' + restOfTemplate + '</div>'
}
$scope.contextMenuData = [ ... ]; /* your usual contextMenuData */
$scope.contextmenuOptions = function() {
   return $scope.contextMenuData;
}; 
josetaira commented 8 years ago

Seems like a workaround has been provided. It's an issue with integration with another library, which isn't really covered in what we can fix (unless there was a dependency in that library - in this case, there's none)