/Angular_JointJS_nzContextMenu-Context_Menu_Controller

Add context menu support for JointJS in Angular (using ContextMenu provided by NG-ZORRO)

Primary LanguageTypeScriptMIT LicenseMIT

ContextMenu for JointJS | Angular & NG-ZORRO

About

- Screenshot

- Environment

- ☆ TL;DR

  1. Know how do the joint.dia.Paper.events work
    • I.e., cell:contextmenu, link:contextmenu, element:contextmenu, and blank:contextmenu
      • cell=vertex+edge; element=vertex; link=edge; blank=paper-cell
  2. Meet the prerequisites (import library, predefine context menu, component initialize, bind event, etc.)
  3. Try the demo ฅ• ω •ฅ

HOW-TO

- Run

  1. $ ./run_app.sh
    • ng add ng-zorro-antd@~8.5.2 for existing project as needed
  2. Visit http://localhost:4200/
    • Change port by ng serve --poll=2000 --port=TARGET_PORT as needed

- Prerequisite

  1. Prepare placeholder for context menu in *.component.html
  2. (Import things in *.component.ts)
    • Services, components, and predefined context menus
    • Shoulde be auto complete if using IDE
  3. Declare and bind target paper, component, and service in *.component.ts
  4. Predefine, bind menus with events, and export context menus in yourMenus.ts

- Implementation

  1. Public APIs
  2. Private function
  • See Demo
    • Note that there's no context menu for element in this demo but use cell instead
      • However, in practice, user should use element and link separately rather than use cell for both because they usually have different context menu
    • You are encouraged to define your own interface to combine MenuAndEvent to increase readability, but it's not required by the library

Angular related

  1. *.component.html

    • Remember to put the placeholder for contextmenu
    • 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>
  2. *.component.ts

  3. yourMenus.ts

    • Declare context menus and corresponding events and bind them to the controller
    • Import and assign as public for HTML rendering
  4. *.pollution.scss


- Demo

  • All demos are shown using cell:contextmenu
    1. 1.1-cell1: No binding event, which will raise warning when init and error when click (as screenshot)
    2. 2.1-cell2: Console log only
    3. 3.1-cell3: Empty children (which requires binding event and won't be render as submenu); EventInfo - X-axis
    4. 3.2-cell4: EventInfo - Y-axis (where user did the right click)
    5. 2.3-cell5: EventInfo - JointJS jQuery Event (the context menu event)
    6. 1.3-cell6: Show title instead of id; EventInfo - CellView (the cell user right clicked on) (undefined for blank event)
    7. 1.4-cell7-disabled-item: Disabled menu item
    8. 1.5-cell8-disabled-submenu: Disabled submenu (children in the menu are still enabled but unreachable)
    9. 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
    10. 1.7-cell10-toggle-disabled: Switch cell9 between enabled and disabled
    11. 1.8-cell11-inner-html: InnerHtml rendering and changing
      • eventInfo.menuItem=the mouse click event; (eventInfo.menuItem.target as HTMLElement)=the menu item

License

  • 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