- Upgrade to stable version when available
- Angular@~9.0.0-rc.7
- JointJs@~3.1.1
- ng-zorro-antd@~8.5.2
- @9.0.0-beta.0 is available but not used
- Know how do the joint.dia.Paper.events work
- I.e.,
cell:contextmenu
,link:contextmenu
,element:contextmenu
, andblank:contextmenu
cell
=vertex+edge;element
=vertex;link
=edge;blank
=paper-cell
- I.e.,
- Meet the prerequisites (import library, predefine context menu, component initialize, bind event, etc.)
- Try the demo ฅ• ω •ฅ
$ ./run_app.sh
ng add ng-zorro-antd@~8.5.2
for existing project as needed
- Visit http://localhost:4200/
- Change port by
ng serve --poll=2000 --port=TARGET_PORT
as needed
- Change port by
- Prepare placeholder for context menu in
*.component.html
- (Import things in
*.component.ts
)- Services, components, and predefined context menus
- Shoulde be auto complete if using IDE
- Declare and bind target paper, component, and service in
*.component.ts
- Predefine, bind menus with events, and export context menus in
yourMenus.ts
Library (contextMenuController.ts)
- Public APIs
menu: ContextMenu
: For HTML renderingonClick(id: string, $eventOnMenuItem?: MouseEvent): void
: Callback events for menu items clickingeventOnMenuItem
: The mouse click event ($event
) for menu item (left click
)
disableMenuItem(menuType: MenuType, targetId: string, setAsDisabled?: boolean): boolean
: Set menu item statussetAsDisabled
:true
=disabled,false
=enabled,leave empty
=toggle
bind(contextMenuInfo: ContextMenuInfo): void
- Bind target paper, nzContextMenuService, and Menu Template (@ViewChild)
unbind(menuType?: MenuType): void
: Reserved. Not used in the demoleave empty
=unbind all 4 kinds of bound events
bindContextMenuWithEvents(menuType: MenuType, contextMenu?: ContextMenu, clickEvents?: ClickEvents)
- (Re)bind predefined context menus and events
- Private function
private extractIdAndEvent(contextMenu: ContextMenu): ClickEvents
- Extract leaf menu items (as expected events) for the following binding check
Example (setContextMenu.ts)
- See Demo
- Note that there's no context menu for
element
in this demo but usecell
instead- However, in practice, user should use
element
andlink
separately rather than usecell
for both because they usually have different context menu
- However, in practice, user should use
- You are encouraged to define your own interface to combine MenuAndEvent to increase readability, but it's not required by the library
- Note that there's no context menu for
-
- Remember to put the placeholder for contextmenu
- Set menu item as unselectable and disable right click on menu items (return false)
- Bind click events and allow using innerHTML
- Copy following html code into your
*.component.html
<nz-dropdown-menu #contextMenuPlaceholder="nzDropdownMenu"> <ul nz-menu class="unselectable" oncontextmenu="return false;"> <ng-container *ngTemplateOutlet="recursiveContextMenu; context:{ $implicit: contextMenu.menu }"></ng-container> <ng-template #recursiveContextMenu let-menuItems> <ng-container *ngFor="let item of menuItems"> <li *ngIf="item.children?.length > 0; else leaf" nz-submenu [nzTitle]="item.title || item.id" [nzDisabled]="item.disabled"> <ul class="unselectable" oncontextmenu="return false;"> <ng-container *ngTemplateOutlet="recursiveContextMenu; context:{ $implicit: item.children }"></ng-container> </ul> </li> <ng-template #leaf> <li nz-menu-item (click)="contextMenu.onClick(item.id, $event)" [nzDisabled]="item.disabled" [innerHTML]="item.title || item.id"></li> </ng-template> </ng-container> </ng-template> </ul> </nz-dropdown-menu>
- Remember to put the placeholder for contextmenu
-
- See prerequisite 2 & 3
- Note that you have to bind
contextMenuComponent
withinngAfterViewInit()
- Note that you have to bind
- See prerequisite 2 & 3
-
- You CANNOT use
style
in innerHTML due to the security policies of Angular- Therefore, you have to use
class
instead - However, you will face
ViewEncapsulation
issue in angular - Workaround: Declare those
*.pollution
CSS explicitly, creat an entry point, and import it instyles.scss
- Therefore, you have to use
- You CANNOT use
- All demos are shown using
cell:contextmenu
1.1-cell1
: No binding event, which will raise warning when init and error when click (as screenshot)2.1-cell2
: Console log only3.1-cell3
: Empty children (which requires binding event and won't be render as submenu); EventInfo - X-axis3.2-cell4
: EventInfo - Y-axis (where user did theright click
)2.3-cell5
: EventInfo - JointJS jQuery Event (the context menu event)1.3-cell6
: Show title instead of id; EventInfo - CellView (the cell user right clicked on) (undefined forblank
event)1.4-cell7-disabled-item
: Disabled menu item1.5-cell8-disabled-submenu
: Disabled submenu (children in the menu are still enabled but unreachable)1.6-cell9-disabled-after-click
: Always disable itself when click- Return and print
true
if the given id was found and disabled status was set
- Return and print
1.7-cell10-toggle-disabled
: Switch cell9 between enabled and disabled1.8-cell11-inner-html
: InnerHtml rendering and changingeventInfo.menuItem
=the mouse click event;(eventInfo.menuItem.target as HTMLElement)
=the menu item
- This project is licensed under the MIT License
- Feel free to modify it as your own version if needed
- Contact me if having any comments :D