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
npm install ngx-contextmenu @angular/cdk
<!doctype html>
at the top of your index.html
Please use ngx-contextmenu@4.2.0 with Angular 5 projects.
<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({
...
})
export class MyContextMenuClass {
public items = [
{ name: 'John', otherProperty: 'Foo' },
{ name: 'Joe', otherProperty: 'Bar' }
];
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}
<ng-template>
element with the contextMenuItem
attribute directive applied.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
.execute
events. The $event
object is of the form { event: MouseEvent, item: any }
where event
is the mouse click eventthat triggered the execution and item
is the current item.divider
input parameter is optional. Items default to normal menu items. If divider
is true
, all the other inputs are ignored.passive
input parameter is optional. If passive
is true
, the menu item will not emit execute events or closethe context menu when clicked.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.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.<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';
}
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:
<context-menu>
can not be placed inside the <ng-template>
that references it.package.json
to reference ngx-contextmenu
instead of angular2-contextmenu
@angular
4.x<ng-template>
instead of <template>
.angular2-contextmenu
to use .ngx-contextmenu
insteadNote: The imperative way of declaring context menu items has been removed. i.e. You can't pass an actions
property to contextMenuService.show.next()
.
visible
and enabled
functionsIf 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;
}
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;
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();
}
}
The context menu can be triggered at any point using the method above. For instance, to trigger the context menuwith 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.
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 witha 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();
}
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;
}
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>
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.
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 {}
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 |
If you need to disable the context menu, you can pass a boolean
to the [disabled]
input:
<context-menu [disabled]="true"></context-menu>
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>
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',
},
];
}
一个比较正确的使用方法:https://github.com/xieziyu/ngx-echarts 1、 npm install echarts --save npm install ngx-echarts --save 如果网速差,可以使用淘宝镜像 2、项目中.angular-cli.json 中添加echarts { "scripts": [ // ... // a
ngx_http_autoindex_module 示例配置 指令 autoindex autoindex_exact_size autoindex_format autoindex_localtime ngx_http_autoindex_module 模块处理以斜线字符(/)结尾的请求并生成一个目录列表。当 ngx_http_index_module 模块找不到索引文件时,通常会将请求传递给
nginx中功能模块抽象接口(Interface),所有要加入到nginx项目中的功能模块必须实现此接口,实现此接口的模块实例将会初始化到全局数组ngx_modules[]中,该数组在项目编译时生成. typedef struct ngx_module_s ngx_module_t;接口定义 : struct ngx_module_s { ngx_uint_t
一.简单添加 (1)this.contextMenustrip1.Item.Add(“toolstripMenuitem1”)------------------添加单个菜单项 (2)this.contextMenustrip1.Item.AddRange(new System.windows.forms.ToolstripItem[]{this.toolstripMenuItem1,this.t
示例:main.xml <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" an
ngx-weui 是一个使用 Angular 构建的 WeUI 组件。 在线示例以及API文档。
ngx-fastdfs 是 nginx + lua +fastdfs 实现分布式图片实时动态压缩。 install 进入docker目录docker build -t fastdfs:dev . 使用 docker -idt -p 80:80 fastdfs:dev /bin/bash进入容器执行/etc/rc.local 测试 进入容器执行test目录下的./test.sh或者直接执行下面脚本
ngx-markdown ngx-markdown is an Angular library that combines... Marked to parse markdown to HTML Prism.js for language syntax highlight Emoji-Toolkit for emoji support KaTeX for math expression rende
ngx-admin Who uses ngx-admin?| Documentation | Installation Guidelines | Angular templates New! Material theme for ngx-admin Material admin theme is based on the most popular Angular dashboard templat
@sweetalert2/ngx-sweetalert2 Official SweetAlert2 integration for Angular This is not a regular API wrapper for SweetAlert (which already works very well alone), it intends to provide Angular-esque ut
ngx-dropzone A lightweight and highly customizable Angular dropzone component for file uploads. For a demo see DEMO. And the CODE for the demo. Install $ npm install --save ngx-dropzone Usage // in ap