Giter Site home page Giter Site logo

isaacplmann / ngx-contextmenu Goto Github PK

View Code? Open in Web Editor NEW
247.0 12.0 90.0 14.03 MB

An Angular component to show a context menu on an arbitrary component

License: MIT License

TypeScript 72.03% JavaScript 5.92% HTML 21.54% SCSS 0.51%
angular contextmenu ngx angular-library

ngx-contextmenu's Introduction

ngx-contextmenu

A context menu built with Angular (10) inspired by ui.bootstrap.contextMenu. Bootstrap classes are included in the markup, but there is no explicit dependency on Bootstrap. Demo Stackblitz example

Installation

  • npm install ngx-contextmenu @angular/cdk
  • import ContextMenuModule.forRoot() into your app module
  • Make sure to include <!doctype html> at the top of your index.html

Usage

Angular 5 support

Please use [email protected] with Angular 5 projects.

Template

<ul>
    <li *ngFor="let item of items" [contextMenu]="basicMenu" [contextMenuSubject]="item">Right Click: {{item?.name}}</li>
</ul>
<context-menu>
  <ng-template contextMenuItem (execute)="showMessage('Hi, ' + $event.item.name)">
    Say hi!
  </ng-template>
  <ng-template contextMenuItem divider="true"></ng-template>
  <ng-template contextMenuItem let-item (execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
    Bye, {{item?.name}}
  </ng-template>
  <ng-template contextMenuItem passive="true">
    Input something: <input type="text">
  </ng-template>
</context-menu>

Component Code

@Component({
  ...
})
export class MyContextMenuClass {
  public items = [
      { name: 'John', otherProperty: 'Foo' },
      { name: 'Joe', otherProperty: 'Bar' }
  ];
  @ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

Context Menu Items

  • Each context menu item is a <ng-template> element with the contextMenuItem attribute directive applied.
  • If the item object is used in the context menu item template, the let-item attribute must be applied to the <ng-template> element. ** Note: ** Make sure to use the item?.property syntax in the template rather than item.property as the item will be initially undefined.
  • Every context menu item emits execute events. The $event object is of the form { event: MouseEvent, item: any } where event is the mouse click event that triggered the execution and item is the current item.
  • The divider input parameter is optional. Items default to normal menu items. If divider is true, all the other inputs are ignored.
  • The passive input parameter is optional. If passive is true, the menu item will not emit execute events or close the context menu when clicked.
  • The enabled input parameter is optional. Items are enabled by default. This can be a boolean value or a function definition that takes an item and returns a boolean.
  • The visible input parameter is optional. Items are visible by default. This property enables you to show certain context menu items based on what the data item is. This can be a boolean value or a function definition that takes an item and returns a boolean.
  • Within the template, you have access to any components and variables available in the outer context.
<context-menu>
  <ng-template contextMenuItem let-item [visible]="isMenuItemType1" [enabled]="false" (execute)="showMessage('Hi, ' + $event.item.name)">
    Say hi, {{item?.name}}!  <my-component [attribute]="item"></my-component>
    With access to the outside context: {{ outsideValue }}
  </ng-template>
</context-menu>
public outsideValue = "something";
public isMenuItemType1(item: any): boolean {
  return item.type === 'type1';
}

Sub-menus

You can specify sub-menus like this:

<ul>
    <li *ngFor="let item of items" [contextMenu]="basicMenu" [contextMenuSubject]="item">Right Click: {{item?.name}}</li>
</ul>
<context-menu>
  <ng-template contextMenuItem [subMenu]="saySubMenu">
    Say...
  </ng-template>
  <context-menu #saySubMenu>
    <ng-template contextMenuItem (execute)="showMessage('Hi, ' + $event.item.name)">
      ...hi!
    </ng-template>
    <ng-template contextMenuItem (execute)="showMessage('Hola, ' + $event.item.name)">
      ...hola!
    </ng-template>
    <ng-template contextMenuItem (execute)="showMessage('Salut, ' + $event.item.name)">
      ...salut!
    </ng-template>
  </context-menu>
  <ng-template contextMenuItem divider="true"></ng-template>
  <ng-template contextMenuItem let-item (execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
    Bye, {{item?.name}}
  </ng-template>
  <ng-template contextMenuItem passive="true">
    Input something: <input type="text">
  </ng-template>
</context-menu>

Notes:

  1. The sub <context-menu> can not be placed inside the <ng-template> that references it.
  2. Sub-menus may be nested as deeply as you wish.

Upgrade from angular2-contextmenu 0.x

  1. Change package.json to reference ngx-contextmenu instead of angular2-contextmenu
  2. Upgrade to @angular 4.x
  3. Use <ng-template> instead of <template>
  4. Update any styles that referenced .angular2-contextmenu to use .ngx-contextmenu instead

Note: The imperative way of declaring context menu items has been removed. i.e. You can't pass an actions property to contextMenuService.show.next().

Using visible and enabled functions

If you need access to properties in your component from within the enabled or visible functions, you can pass in an arrow function.

<ng-template ... [visible]="isMenuItemOutsideValue">
public outsideValue = "something";
public isMenuItemOutsideValue = (item: any): boolean => {
  return item.type === this.outsideValue;
}

Multiple Context Menus

You can use multiple context menus in the same component if you would like.

<ul>
    <li *ngFor="let item of items" [contextMenu]="basicMenu" [contextMenuSubject]="item">{{item?.name}}</li>
</ul>
<context-menu #basicMenu>
  ...
</context-menu>

<ul>
    <li *ngFor="let item of items" [contextMenu]="otherMenu" [contextMenuSubject]="item">{{item?.name}}</li>
</ul>
<context-menu #otherMenu>
  ...
</context-menu>
@ViewChild('basicMenu') public basicMenu: ContextMenuComponent;
@ViewChild('otherMenu') public otherMenu: ContextMenuComponent;

Context Menu In a Different Component

If your <context-menu> component is in a different component from your list, you'll need to wire up the context menu event yourself.

<ul>
    <li *ngFor="let item of items" (contextmenu)="onContextMenu($event, item)">Right Click: {{item.name}}</li>
</ul>
import { ContextMenuService } from 'ngx-contextmenu';

@Component({
  ...
})
export class MyContextMenuClass {
  public items = [
      { name: 'John', otherProperty: 'Foo' },
      { name: 'Joe', otherProperty: 'Bar' }
  ];

  // Optional
  @Input() contextMenu: ContextMenuComponent;

  constructor(private contextMenuService: ContextMenuService) {}

  public onContextMenu($event: MouseEvent, item: any): void {
    this.contextMenuService.show.next({
      // Optional - if unspecified, all context menu components will open
      contextMenu: this.contextMenu,
      event: $event,
      item: item,
    });
    $event.preventDefault();
    $event.stopPropagation();
  }
}

Triggering the Context Menu with a Different Event

The context menu can be triggered at any point using the method above. For instance, to trigger the context menu with a left click instead of a right click, use this html:

<ul>
    <li *ngFor="let item of items" (click)="onContextMenu($event, item)">Left Click: {{item.name}}</li>
</ul>

This could be (keydown), (mouseover), or (myCustomEvent) as well.

Positioning the Context Menu around an element

If you want to override the context menu positioning to be appended to an element instead of based on mouse position, provide an anchorElement to the contextMenuService. This makes sense if you want to trigger the context menu with a non-MouseEvent.

public onContextMenu($event: KeyboardEvent, item: any): void {
  this.contextMenuService.show.next({
    anchorElement: $event.target,
    // Optional - if unspecified, all context menu components will open
    contextMenu: this.contextMenu,
    event: <any>$event,
    item: item,
  });
  $event.preventDefault();
  $event.stopPropagation();
}

Custom Styles

The html that is generated for the context menu looks like this:

<div class="dropdown ngx-contextmenu">
  <ul class="dropdown-menu">
    <li>
      <a><!-- the template for each context menu item goes here --></a>
      <span><!-- the template for each passive context menu item goes here --></span>
    </li>
  </ul>
</div>

You can key off of the ngx-contextmenu class to create your own styles. Note that the ul.dropdown-menu will have inline styles applied for position, display, left and top so that it will be positioned at the cursor when you right-click.

.ngx-contextmenu .dropdown-menu {
  border: solid 1px chartreuse;
  background-color: darkgreen;
  padding: 0;
}
.ngx-contextmenu li {
  display: block;
  border-top: solid 1px chartreuse;
  text-transform: uppercase;
  text-align: center;
}
.ngx-contextmenu li:first-child {
  border-top:none;
}
.ngx-contextmenu a {
  color:chartreuse;
  display: block;
  padding: 0.5em 1em;
}
.ngx-contextmenu a:hover {
  color:darkgreen;
  background-color:chartreuse;
}

Bootstrap 4

If you're using Bootstrap 4, you can specify a useBootstrap4 property in the forRoot function of the ContextMenuModule in order to get the appropriate class names. Like this:

@NgModule({
  import: [
    ContextMenuModule.forRoot({
      useBootstrap4: true,
    }),
  ],
})
export class AppModule {}

Or, if you want to repeat yourself, you can add a useBootstrap4 attribute to each context-menu component. Like this:

<context-menu [useBootstrap4]="true"></context-menu>

Different styling on menus

If you want to style one menu differently than other menus, you can add a custom style to the menu.

<context-menu [menuClass]="'mystyle'"></context-menu>

Please note that the style needs to be global to affect the menu, since the menu element is added to the page outside the component that triggers the menu.

AutoFocus

You can optionally set focus on the context menu whenever it opens. This enables a user to easily tab through the context menu items and press enter to select them.

@NgModule({
  import: [
    ContextMenuModule.forRoot({
      autoFocus: true,
    }),
  ],
})
export class AppModule {}

Keyboard navigation

You can use the keyboard to manipulate the context menu. Note: Keyboard navigation should be used in conjunction with autoFocus, since key events are only captured when the context menu is focused.

Key Action
ArrowDown Move to next menu item (wrapping)
ArrowUp Move to previous menu item (wrapping)
ArrowRight Open submenu of current menu item if present
ArrowLeft Close current menu unless already at root menu
Enter | Space Open submenu or execute current menu item
Esc Close current menu

Disable Context Menu

If you need to disable the context menu, you can pass a boolean to the [disabled] input:

<context-menu [disabled]="true"></context-menu>

Close event emitter

There is a (close) output EventEmitter that you can subscribe to for notifications when the context menu closes (either by clicking outside or choosing a menu item).

<context-menu (close)="processContextMenuCloseEvent()"></context-menu>

Dynamic context menu

The items in the context menu are completely controlled by the contextMenuActions object.

<ul>
    <li *ngFor="item in items" [contextMenu]="myContextMenu" [contextMenuSubject]="item">Right Click: {{item.name}}</li>
</ul>
<context-menu #myContextMenu>
  <ng-template *ngFor="let action of contextMenuActions" contextMenuItem let-item
    [visible]="action.visible" [enabled]="action.enabled" [divider]="action.divider"
    (execute)="action.click($event.item)">
    {{ action.html($event.item) }}
  </ng-template>
</context-menu>
@Component({
  ...
})
export class MyContextMenuClass {
  public items = [
      { name: 'John', otherProperty: 'Foo', type: 'type1' },
      { name: 'Joe', otherProperty: 'Bar', type: 'type2' }
  ];
  @ViewChild(ContextMenuComponent) public contextMenu: ContextMenuComponent;
  public contextMenuActions = [
        {
          html: (item) => `Say hi!`,
          click: (item) => alert('Hi, ' + item.name),
          enabled: (item) => true,
          visible: (item) => item.type === 'type1',
        },
        {
          divider: true,
          visible: true,
        },
        {
          html: (item) => `Something else`,
          click: (item) => alert('Or not...'),
          enabled: (item) => false,
          visible: (item) => item.type === 'type1',
        },
      ];
}

ngx-contextmenu's People

Contributors

carlmon avatar cwdaniel avatar czeckd avatar daevid66 avatar dbusacca avatar henkensm avatar hrueger avatar isaacplmann avatar kgriffiths avatar kierandotco avatar mattlewis92 avatar raulprop avatar sgotre avatar sonce avatar sroucheray avatar vstets avatar yura13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngx-contextmenu's Issues

Little problem using ngx-contextmenu with Safari

Using nix-contextmenu with Safari the "original" context menu is disabled but beside the ngx-contextmenu another native context menu appears (Search with Google, Add to iTunes). How could I prevent this native one?

Allow closing the menu from a script. Also problems with spaces in input/passive.

Hi, thank you for the nice context menu.

  1. Is there a way to close the menu via script, for instance on an event. In particular,
    if I have a passive menu with an input text box, in response to a keyup.enter event, I want
    to close the menu.

  2. For some reason I cannot type spaces into an input box.

<ng-template contextMenuItem passive="true"> Rename to: <input #rename type="text" (keyup.enter)="onEnter(rename.value)"> </ng-template>

The same input box allows spaces elsewhere.

Thank you,

-- Thor

How to integrate with D3.js

Hi,

this isn't a problem with the component, but more of a request for help. I'm working on an Angular 4 project with D3.js and I wanted to add context menus when right clicking nodes on a graph. As the d3-contextmenu plugin hasn't been updated to D3V4 or Typescript, I tried adding ngx-contextmenu to my SVG element. Now, I wanted to obtain the nodes right-clicked and trigger a function on them from the context-menu. Any pointers on how to achieve this?

Issue updating to Angular 4.x

Hello,

In systemjs.config.js, I included the file:

'ngx-contextmenu': 'npm:ngx-contextmenu'

and updatage systemjs to 0.20.12.

It seems it requires a new dependency to babel in order to transpile ngx-contextmenu ES2015 code to commonjs code.

I don't know if previous angular2-contextmenu was coded in commonjs, but I hadn't that dependency problem.

I didn't find yet which nom babel is required for systemjs.

Thank You for support,
Anthony Breneliรจre

Changing start position of context menu

Hello,

I've been playing with ngx-contextmenu and I wanted to ask how can I change where the context menu is created when I right click. Currently I'm applying it to an element that is at the very top of my screen. The context menu's bottom left corner starts at the pointer and grows upwards. As a result, most of it is off the screen for elements at the top. Is there anyway I can easily change this?

Thanks!

Few context menus

Hello,

Is some possibility to add few context menus?
I have a case when one menu I should add to the page and another one to "ng-bootstrap" modal dialog. I have tried to implement few context menus, but it doesn't work.

Thanks!

separator/divider

From @gjenner on March 21, 2017 15:23

is it possible to add a divider (or separator) in code rather than HTML?

Copied from original issue: isaacplmann/angular2-contextmenu#58

Can't bind to 'contextMenu' since it isn't a known property of 'li'

Hello everyone,

I followed the instruction to work with the ngx-contextmenu library.
After implementing, I only get an error: "Can't bind to 'contextMenu' since it isn't a known property of 'li'".

I don't know what went wrong.
Could you help me plz?

Kind regards,
David.

Z-index of context menu

Would it be possible to set the z-index in hard with bootstrap 4 ?
With angular view method the context menu is displayed below the parent elements.
I fixed the css but the z-index should be that of a popover or a tooltip by default no ?

.ngx-contextmenu {
    z-index: $zindex-tooltip;
}

Is there a way to access markup ng-template content trough @ViewChild()

Is there a way to access markup of the context-menu template ?
I tried to access it trough
@ViewChild('myContextMenu') public fileContextMenu; but I can't find anything in the object.

<context-menu #myContextMenu>
  <ng-template contextMenuItem let-item>
    <a>
      <i class="zmdi zmdi-open-in-browser"></i> Open
    </a>
  </ng-template>
  <ng-template contextMenuItem let-item>
    <a data-target="modal-delete">
      <i class="zmdi zmdi-delete"></i>Delete
    </a>
  </ng-template>
</context-menu>

How to get mouseover ng-template?

I want to display help to user before user click on specific context menu link so i want to mouseover event of this menu it's possible?
i want something like that.
dashboard

custom css not working

I've tried to customise the context menu by applying your sample CSS code to my component's CSS file. Unfortunately it's not working. I tried inspecting my code, the problem is that the custom CSS is not applying to the code. Any suggestions ?

Subject is not a constructor

I can't seem to get rid of this error when I use the component. It doesn't seem to like that the service uses the 'Subject' from rxjs as a constructor, i.e. 'new Subject()';

ERROR TypeError: Subject_1.Subject is not a constructor
    at new ContextMenuService (contextMenu.service.js:23)
    at FakeModuleInjector.get (module.ngfactory.js:144)
    at FakeModuleInjector.getInternal (module.ngfactory.js:256)
    at FakeModuleInjector.NgModuleInjector.get (ng_module_factory.ts:141)
    at resolveDep (provider.ts:504)
    at createClass (provider.ts:371)
    at createDirectiveInstance (provider.ts:192)
    at createViewNodes (view.ts:290)
    at callViewAction (view.ts:699)
    at execComponentViewsAction (view.ts:643)
    at createViewNodes (view.ts:355)
    at Object.createEmbeddedView (view.ts:208)
    at TemplateRef_.createEmbeddedView (refs.ts:519)
    at ViewContainerRef_.createEmbeddedView (refs.ts:274)
    at NgIf._updateView (ng_if.ts:159)

Providing the context menu on mouseover instead of right mouse click

Hi,

Thanks for OS this cool utility. I integrated it and it works quite nicely.

On the project I integrated this in, they would love to have a way of making the context menu show on any mouseover event. As I saw in the source code, this is currently not supported. Do you think this could be added as an option or do you have a practical reason not to add this?

If you want to, I could provide a PR with the necessary changes to do so.

Kind regards

Problem loading the module with Angular Seed

My project seems to struggle with loading the contextmenu module. When I launch the app, I get this console error:

(SystemJS) XHR error (404 Not Found) loading http://localhost:5555/node_modules/traceur.js Error: XHR error (404 Not Found) loading http://localhost:5555/node_modules/traceur.js at XMLHttpRequest.wrapFn [as __zone_symbol___onreadystatechange] (http://localhost:5555/node_modules/zone.js/dist/zone.js?1492524996291:1199:29) [<root>] at Zone.runTask (http://localhost:5555/node_modules/zone.js/dist/zone.js?1492524996291:165:47) [<root> => <root>] at XMLHttpRequest.ZoneTask.invoke (http://localhost:5555/node_modules/zone.js/dist/zone.js?1492524996291:460:38) [<root>] Error loading http://localhost:5555/node_modules/traceur.js Unable to load transpiler to transpile http://localhost:5555/node_modules/ngx-contextmenu/lib/index.js Error loading http://localhost:5555/node_modules/ngx-contextmenu/lib/index.js as "ngx-contextmenu" from http://localhost:5555/app/app.module.js

I want to highlight the last bit Error loading http://localhost:5555/node_modules/ngx-contextmenu/lib/index.js as "ngx-contextmenu" from http://localhost:5555/app/app.module.js as it seems that the module is not being loaded. Am I supposed to use some other name than ngx-contextmenu as the module name?

From the sources tool in Chrome, I can confirm that it's not being loaded. It is however in my project. Any input for what might be wrong here?

defining the menu item from code behind

As the support for 'actions' has been removed now, how can we define the menu items dynamically from code behind? I actually define the menu items and its action based on the data being displayed at run time.

How can I disable Keyboard navigation?

Hi. I like your context menu. Thanks a lot for your kindly help!

I am trying to use your context menu in HTML canvas, which actually I handle it by paper.js. I make a textarea in context menu. The program code is shown in below. Unfortunately, while typing in the textarea, I get an error when I key press down with "ArrowUp" or "ArrowDown". The error is about "Maximum call stack size exceeded" (shown in below), properly refer to the method "InjectionRegistry.prototype.getByType = function (type) {", which is used in "injection-registry.service.js".

Therefore, I am asking for

  1. solution for this issue if you can help?
  2. is there any way to disable "Keyboard navigation", especially "ArrowUp" and "ArrowDown" for the context menu?

Thanks!

Code:

<context-menu #textMenu>
  <ng-template contextMenuItem passive="true" [visible]="true" [enabled]="false">
    <textarea #editorArea id='editor' [style.width]="tempTextWidth" [style.height]="tempTextHeight"
              (blur)="onChangeOnTextArea($event.target)"
              (keyup)="onChangeOnTextArea($event.target)"
              (paste)="onChangeOnTextArea($event.target)"
              (copy)="onChangeOnTextArea($event.target)"
              (cut)="onChangeOnTextArea($event.target)"
              (resize)="onChangeOnTextArea($event.target)"
    >{{tempText}}</textarea>
  </ng-template>
</context-menu>

<div class="container-fluid">
  <div class="row">
    <canvas #myCanvas class="main-view col-12 mt-2" resize (click)="onContextMenu($event, item)"></canvas>
  </div>
</div>

Error:

ERROR RangeError: Maximum call stack size exceeded
at ContextMenuInjectorService.webpackJsonp.../../../../ngx-contextmenu/lib/injection/injection-registry.service.js.InjectionRegistry.getByType (injection-registry.service.js:7)
at ContextMenuService.webpackJsonp.../../../../ngx-contextmenu/lib/contextMenu.service.js.ContextMenuService.getLeafMenu (contextMenu.service.js:31)
at ContextMenuService.webpackJsonp.../../../../ngx-contextmenu/lib/contextMenu.service.js.ContextMenuService.isLeafMenu (contextMenu.service.js:38)
...

Menu not working

Hi,

The menu has no styling (just looks like a regular li bullet point), and sometimes comes up all the way at the left of the screen, instead of at the cursor. I am using Angular 4.0.3 and ngx-contextmenu 1.2.1.

App module:
import { ContextMenuModule } from 'ngx-contextmenu';

Component:

import { ContextMenuComponent } from 'ngx-contextmenu';
...
  @ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;

HTML:

<div style="padding-top: 10px; width: 100%; display: inline-block;"  [contextMenu]="basicMenu">
...

<context-menu>
  <ng-template contextMenuItem>
    Say hi!
  </ng-template>
</context-menu>

What am I doing wrong?
Thanks

latest release, context menu does not close on selection

latest release, context menu does not close on selection

no_close

let me know if you need more info

config:

  <div (click)="$event.preventDefault()">
            <small class="debug">{{me}}</small>
            <h4 style="color: #a9a9a9">total timelines: {{m_campaignTimelinesModels?.size}}</h4>

            <hr class="dottedHR">
            <div id="dragcontainer">
                <screen-template #st class="draggableTimeline"
                                 *ngFor="let screenTemplate of m_screenTemplates$ | async; trackBy: trackByFn"
                                 (contextmenu)="onContextMenu($event, screenTemplate)"
                                 (click)="_onScreenTemplateSelected(screenTemplate, st)"
                                 (onDivisionDoubleClicked)="_onDivisionDoubleClicked($event)"
                                 [setTemplate]="screenTemplate">
                </screen-template>
            </div>
            <context-menu>
                <ng-template contextMenuItem let-item (execute)="_onContextClicked('load props ',$event.item)">
                    timeline properties for {{item?.name}}
                </ng-template>
                <ng-template contextMenuItem divider="true"></ng-template>
                <ng-template contextMenuItem (execute)="_onContextClicked('edit',$event.item)"><span i18n>edit layout</span></ng-template>
                <ng-template contextMenuItem (execute)="_onContextClicked('nextch',$event.item)"><span i18n>next channel</span></ng-template>
            </context-menu>
        </div>

regards

Sean

Getting "No provider for ContextMenuService!" error when adding a <context-menu> element

I've tried to follow the README example, i get the following error when attempting the simplest example usage:

ERROR Error: No provider for ContextMenuService!

Unhandled Promise rejection: No provider for ContextMenuService! ; Zone: <root> ; Task: Promise.then ; Value: Error: No provider for ContextMenuService!

When attempting to add ContextMenuService in the "providers" section of the decorator i get:

ERROR Error: No provider for ContextMenuInjectorService!
Unhandled Promise rejection: No provider for ContextMenuInjectorService! ; Zone: <root> ; Task: Promise.then ; Value: Error: No provider for ContextMenuInjectorService!

how do I disable the menu?

I have some items that simply should not have a context menu, but if I disable all of the menu items, *ngIf the template, etc the menu does not go away. I have a bunch of similar items wrapped in a component that can all be interacted with in different ways, and some cannot be interacted with.

Is there a way to do this?

Sub-Menus

From @AndreAlves10 on March 1, 2017 10:54

Hello @isaacplmann,

Is it possible to create sub-menus? Just like the following:

submenu

I have an angular-cli project, in my Typescript file I have the following:

self.contextMenuService.show.next({
        actions: self.contextMenuItems,
        event: props.event,
        item: props.event.target
      });

And my HTML is like:

<context-menu>
    <template contextMenuItem (execute)="showMessage('Hi, ' + $event.item.name)">
        Say hi!
        <template contextMenuItem (execute)="showMessage('Hi, ' + $event.item.name)">
            Say hi!
        </template>
    </template>
    <template contextMenuItem divider="true"></template>
    <template contextMenuItem let-item (execute)="showMessage($event.item.name + ' said: ' + $event.item.otherProperty)">
        Bye, {{item?.name}}
    </template>
    <template contextMenuItem passive="true">
        Input something: <input type="text">
    </template>
</context-menu>

Thank you!

Copied from original issue: isaacplmann/angular2-contextmenu#52

Dynamic context menu support for html other than simple strings.

I'm trying to make a dynamic context menu with html more complicated than a simple string
but instead the html tags are just shown as raw strings. See image below. My real use case
is wanting an input text box. I also do not seem to be able to set 'passive' in dynamic context menu.

Thanks.

public contextMenuActions = [
    {
      html: () => `Say hi!`,
      click: () => this.doSomething(),
      enabled: () => true,
      visible: () => true,
    },
    {
      html: () => `Say <b>hi</b>!`,
      click: () => this.doSomething(),
      enabled: () => true,
      visible: () => true,
    },
    {
      html: () => `Rename to: <input #rename type="text" (keyup.enter)="onEnter(rename.value)">`,
      click: () => this.doSomething(),
      enabled: () => true,
      visible: () => true,
      passive: () => true,
    },
  ];

image

Keep imperative approach for defining menu items?

From @rsinger86 on October 8, 2016 22:59

hi, thanks for making this component - it's very useful! I just had a suggestion...

In my app, I want to re-use the same context menu in many different components. With the new declarative approach, there is no easy way for me to duplicate these menu items across multiple components, because of how the ContextMenuComponent uses ContentChildren, which hardcodes the item definitions into templates. But with the imperative approach, it's easy to define these items in a TypeScript module that I import various places.

Copied from original issue: isaacplmann/angular2-contextmenu#15

Multiple Context menus cause firing of wrong events

I have 2 components on the page, The first component contains a context menu and a child component

<div class="{{cssClass}}" [formGroup]="formGroup">
 <span [contextMenu]="basicMenu" [contextMenuSubject]="'test'"
        [ngClass]="{'col-md-10': true, 'context-item' : this.mode === this.componentModes.ADMIN}"
        [hidden]="formGroup.get(formcontrolname).get('test').value.mode === 'edit'"
        [innerHtml]="formGroup.get(formcontrolname).get('test').value.label"></span>

   <context-menu  #basicMenu [disabled]="this.mode !== this.componentModes.ADMIN">
      <ng-template contextMenuItem (execute)="editMedicalField($event.item)">
        Edit Field
      </ng-template>
    </context-menu>
</div>

<!-- THIS CONTAINS THE OTHER CONTEXT SEE BELOW-->
<custom-field-selector [section]="'Eligibility'" *ngIf="mode === componentModes.ADMIN" [selectedFields]="formGroup.get(formcontrolname).get('fields')"
  (onSaveFields)="onSaveFields($event)" #fieldSelector></ustom-field-selector>

editMedicalField(groupName) {
    let field = this.formGroup.get(this.formcontrolname).get(groupName);
    field.patchValue({ mode: 'edit' });
    field.enable();

  }

the child component (custom-field-selector) has

<div class="{{cssClass}}" [formGroup]="formGroup">
 <div [formGroupName]="i" class="form-group" *ngFor="let field of fields.controls; let i=index; trackBy: fieldTrackIt">
          <label  [contextMenu]="dynamicMenu" [contextMenuSubject]="{field: field, idx: i, emitter: onFieldRemove}">{{field.value.definition.label}}</label>
  </div>

    <context-menu #dynamicMenu [disabled]="this.mode !== this.componentModes.ADMIN">
      <ng-template contextMenuItem [visible]="allowedToEditBound" (execute)="editField($event.item)">
        Edit Field
      </ng-template>
      <ng-template contextMenuItem [visible]="allowedToDeleteBound" (execute)="deleteField($event.item)">
        Delete Field
      </ng-template>
    </context-menu>
</div>


 public allowedToEditBound = this.allowedToEdit.bind(this);
  public allowedToDeleteBound = this.allowedToDelete.bind(this);

  allowedToEdit() {
    return this.mode === this.componentModes.ADMIN
      && this.permissions
      && this.permissionsService.hasPermission(...this.permissions);
  }

  allowedToDelete(item: { field: FormGroup, idx: number }) {
    if(!item.field){
      return false;
    }
    return item.field.value.definition.canBeDeleted
      && this.mode === CONST.COMPONENT_MODE.ADMIN
      && this.permissions
      && this.permissionsService.hasPermission(...this.permissions);
  }

When the page loads and i try and edit the top span with the #basicMenu it fires the events of the child component, which causes errors... I can not get a plunkr together due to time constraints, but any ideas? seems the #contextName and context subject are getting confused and losing track of what events to fire...

So on right click of parent it fires the child allowedToDelete and allowedToEdit, but passes the value of the parent ContextSubject

angular 4.2.2
ngx-context 1.2.0

Downgrading to angular1.5

Hi ,

I have used the ngx-contextmenu in my application which is developed on Angular4.

now i need to downgrade my entire application to angular1.5 .

i am facing an issue with ngx-xontextmenu after downgrading.

i am getting the following error

View Container not found! ngUpgrade needs to manually set this via setRootViewContainer.

i tried injecting the injection service and using the setRootViewContainer , i am passing the component which uses the ngx-contextmenu as viewChild ,

but i ended up getting another error
hostView is not defined ,

Can you please tell me on what component must be passed

Thanks

Problem with context menu position

In some situations context menu is opened from bottom and upper elements are hidden.
But if I right click a little upper it is opened correctly/
screenshot_3
screenshot_4

SystemJS build with rollup

From @anthonyBR on February 15, 2017 17:44

Hello,

When I generate my angular2 project:
node_modules\.bin\rollup -c rollup-config.js

I have the error in the title:

?   'ContextMenuComponent' is not exported by node_modules\angular2-contextmenu\
angular2-contextmenu.js

To bundle my project, I use rollup, as described here:
https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

As said in the documentation:
Rollup can only Tree Shake ES2015 modules which have import and export statements.

And ContextMenuComponent has no export statement.

The project works well when I start the project with systemjs.

Thank you for help,
A. Breneliere

Copied from original issue: isaacplmann/angular2-contextmenu#48

How to set contextmenu location in DOM

I have a canvas with a contextmenu, like

<div>
    <canvas [contextMenu]="contextmenu"></canvas>
    <context-menu>
        <ng-template contextMenuItem>
            ...
        </ng-template>
    </context-menu>
</div>

And the canvas need to support full screen. When I let the 'div' element full screen, the contextmenu is under 'app-root', outside the full screen element. How to make the contextmenu under 'div' element?

Can you dynamically add a sub-menu?

I'm dynamically creating menu items but I also want to add sub-menus dynamically, is that possible? If I add this to the template it works [submenu]="mySubMenu" but if I try and add the reference dynamically with [submenu]="action.submenu" it doesn't.

<context-menu #myContextMenu>
    <ng-template *ngFor="let action of contextMenuActions" contextMenuItem let-item
                 [visible]="action.visible" [enabled]="action.enabled" [divider]="action.divider" [subMenu]="action.submenu"
                 (execute)="action.click($event.item)">
        {{ action.html() }}
    </ng-template>
</context-menu>

<context-menu #mySubMenu>
    <ng-template *ngFor="let action of contextSubMenuActions" contextMenuItem let-item
                 [visible]="action.visible" [enabled]="action.enabled" [divider]="action.divider"
                 (execute)="action.click($event.item)">
        {{ action.html() }}
    </ng-template>
</context-menu>

Here is the code to generate the menu items in the parent context menu:

this.contextMenuActions = [
            {
                html: () => "Label",
                click: () => this.contextMenuClick(),
                enabled: () => true,
                visible: () => true,
                submenu: () => "mySubMenu"
            ];

context menu - Chrome vs IE

Hi - I am trying to use this component in our application. Our primary browser is IE 11. I believe, I have done all the wiring right but context menu is not showing up in my app. However it does show up if I open my app in chrome. Is there anything different I need to do to make it work in IE 11?

Also this link work in chrome but not in IE - https://isaacplmann.github.io/ngx-contextmenu/

Can you please advise? Thank you very much

Gerry

Allow undefined item

From @LeGaby on February 28, 2017 16:25

Hi @isaacplmann!

I have 2 context menus in one component and I'm trying to get one of them with the ViewChild annotation.
In the HTML of my component :
<button type="button" (click)="onContextMenu($event, item)"></button> <context-menu #allSitesMenu>...</context-menu>

In the corresponding typescript :
@ViewChild('allSitesMenu') allSitesMenu: ContextMenuComponent;

When I log it in the console during the ngAfterViewInit lifecycle, I see the ContextMenuComponent exists but it has menuElement property to undefined. That's why it returns the following error when I'm trying to open it with the ContextMenuService :
TypeError: Cannot read property 'nativeElement' of undefined

Do you have any idea why this property is undefined ?

Copied from original issue: isaacplmann/angular2-contextmenu#51

scrolling issue with the context menu

From @shahbazshueb on January 10, 2017 10:1

When the context-menu is open in a scrollable content then the menu also scrolls down instead of staying fixed at its position. The menu should close when the content is scrolled down or it should stay fixed at the position.
context menu scroll problem

Copied from original issue: isaacplmann/angular2-contextmenu#40

Unable to install ngx-contextmenu for Angular 2 (UNMET PEER DEPENDENCIES)

Hello, I tried to install ngx-contextmenu for my angular 2 app but when I type "npm install --save ngx-contextmenu" on prompt command, i get :

`+--UNMET PEER DEPENDENCY @angular/[email protected]
+-- UNMET PEER DEPENDENCY @angular/[email protected]
+-- UNMET PEER DEPENDENCY bootstrap@~3.3.x
-- [email protected]

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN [email protected] requires a peer of bootstrap@~3.3.x but none was installed.
npm WARN [email protected] requires a peer of @angular/common@^4.0.0 but none was installed.
npm WARN [email protected] requires a peer of @angular/core@^4.0.0 but none was installed.

Is there any way to fix it ?

Thanks

Not compatible with Angular 5.0

FYI

ERROR in ../node_modules/ngx-contextmenu/lib/contextMenu.options.d.ts(1,10): error TS2305: Module '"C:/.../node_modules/@angular/core/core"' has no exported member 'OpaqueToken
'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.