On right click it throws below error.

ERROR TypeError: Cannot read properties of undefined (reading 'pageX')
    at ContextMenu.show (vendor.js:137169:24)
    at TreeTableContextMenuDemo.onContextMenuSelection (main.js:380:19)
    at TreeTableContextMenuDemo_Template_p_treeTable_onContextMenuSelect_2_listener (main.js:417:80)
    at executeListenerWithErrorHandling (vendor.js:81604:12)
    at Object.wrapListenerIn_markDirtyAndPreventDefault [as next] (vendor.js:81635:18)
    at ConsumerObserver.next (vendor.js:32287:25)
    at SafeSubscriber._next (vendor.js:32256:22)
    at SafeSubscriber.next (vendor.js:32229:12)
    at vendor.js:32066:20
    at errorContext (vendor.js:35605:5)

enter image description here

<div class="card">
  <p-toast [style]="{ marginTop: '80px' }"></p-toast>

  <p-treeTable
    [value]="files"
    [columns]="cols"
    dataKey="name"
    [(selection)]="selectedNode"
    selectionMode="multiple"
    contextMenuSelectionMode="joint"
    [metaKeySelection]="true"
    [(contextMenuSelection)]="selectedNode"
    [contextMenu]="cm"
    (onContextMenuSelect)="onContextMenuSelection(cm)"
    [scrollable]="true"
    [tableStyle]="{'min-width':'50rem'}"
  >
    <ng-template pTemplate="header" let-columns>
      <tr>
        <th *ngFor="let col of columns">{{ col.header }}</th>
      </tr>
    </ng-template>
    <ng-template
      pTemplate="body"
      let-rowNode
      let-rowData="rowData"
      let-columns="columns"
    >
      <tr [ttContextMenuRow]="rowNode" [ttSelectableRow]="rowNode">
        <td *ngFor="let col of columns; let i = index">
          <p-treeTableToggler
            [rowNode]="rowNode"
            *ngIf="i === 0"
          ></p-treeTableToggler>
          {{ rowData[col.field] }}
        </td>
      </tr>
    </ng-template>
  </p-treeTable>

  <p-contextMenu #cm [model]="items"></p-contextMenu>
</div></pre> </code>

.ts file 
import { Component, OnInit } from '@angular/core';
import { MenuItem, MessageService, TreeNode } from 'primeng/api';
import { NodeService } from '../../service/nodeservice';

interface Column {
  field: string;
  header: string;
}

@Component({
  selector: 'tree-table-context-menu-demo',
  templateUrl: './tree-table-context-menu-demo.html',
  providers: [MessageService],
})
export class TreeTableContextMenuDemo implements OnInit {
  files!: TreeNode[];

  selectedNode!: TreeNode[];

  cols!: Column[];

  items!: MenuItem[];

  constructor(
    private nodeService: NodeService,
    private messageService: MessageService
  ) {}

  ngOnInit() {
    this.nodeService.getFilesystem().then((files) => (this.files = files));

    this.cols = [
      { field: 'name', header: 'Name' },
      { field: 'size', header: 'Size' },
      { field: 'type', header: 'Type' },
    ];

    this.items = [
      {
        label: 'View',
        icon: 'pi pi-search',
        command: (event) => this.viewFile(this.selectedNode),
      },
      {
        label: 'Toggle',
        icon: 'pi pi-sort',
        command: (event) => this.toggleFile(this.selectedNode),
      },
    ];
  }
  onContextMenuSelection(contextMenu) {
    let selectedNodeIsChildren = false;
    for (let i = 0; i < this.selectedNode.length; i++) {
      if (this.selectedNode[i].children.length == 0) {
        selectedNodeIsChildren = true;
        break;
      } else {
        selectedNodeIsChildren = false;
      }
    }
    if (selectedNodeIsChildren) {
      contextMenu.hide();
    } else {
      contextMenu.show();
    }
  }
  viewFile(node: any) {
    this.messageService.add({
      severity: 'info',
      summary: 'File Selected',
      detail: node.data.name + ' - ' + node.data.size,
    });
  }

  toggleFile(node: any) {
    node.expanded = !node.expanded;
    this.files = [...this.files];
  }
}

.service file

@Injectable()
export class NodeService {

  getFileSystemNodesData() {
    return [
      {
        data: {
          name: 'Applications',
          size: '200mb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'Angular',
              size: '25mb',
              type: 'Folder',
            },
            children: [
              {
                data: {
                  name: 'angular.app',
                  size: '10mb',
                  type: 'Application',
                },
              },
              {
                data: {
                  name: 'cli.app',
                  size: '10mb',
                  type: 'Application',
                },
              },
              {
                data: {
                  name: 'mobile.app',
                  size: '5mb',
                  type: 'Application',
                },
              },
            ],
          },
          {
            data: {
              name: 'editor.app',
              size: '25mb',
              type: 'Application',
            },
          },
          {
            data: {
              name: 'settings.app',
              size: '50mb',
              type: 'Application',
            },
          },
        ],
      },
      {
        data: {
          name: 'Cloud',
          size: '20mb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'backup-1.zip',
              size: '10mb',
              type: 'Zip',
            },
          },
          {
            data: {
              name: 'backup-2.zip',
              size: '10mb',
              type: 'Zip',
            },
          },
        ],
      },
      {
        data: {
          name: 'Desktop',
          size: '150kb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'note-meeting.txt',
              size: '50kb',
              type: 'Text',
            },
          },
          {
            data: {
              name: 'note-todo.txt',
              size: '100kb',
              type: 'Text',
            },
          },
        ],
      },
      {
        data: {
          name: 'Documents',
          size: '75kb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'Work',
              size: '55kb',
              type: 'Folder',
            },
            children: [
              {
                data: {
                  name: 'Expenses.doc',
                  size: '30kb',
                  type: 'Document',
                },
              },
              {
                data: {
                  name: 'Resume.doc',
                  size: '25kb',
                  type: 'Resume',
                },
              },
            ],
          },
          {
            data: {
              name: 'Home',
              size: '20kb',
              type: 'Folder',
            },
            children: [
              {
                data: {
                  name: 'Invoices',
                  size: '20kb',
                  type: 'Text',
                },
              },
            ],
          },
        ],
      },
      {
        data: {
          name: 'Downloads',
          size: '25mb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'Spanish',
              size: '10mb',
              type: 'Folder',
            },
            children: [
              {
                data: {
                  name: 'tutorial-a1.txt',
                  size: '5mb',
                  type: 'Text',
                },
              },
              {
                data: {
                  name: 'tutorial-a2.txt',
                  size: '5mb',
                  type: 'Text',
                },
              },
            ],
          },
          {
            data: {
              name: 'Travel',
              size: '15mb',
              type: 'Text',
            },
            children: [
              {
                data: {
                  name: 'Hotel.pdf',
                  size: '10mb',
                  type: 'PDF',
                },
              },
              {
                data: {
                  name: 'Flight.pdf',
                  size: '5mb',
                  type: 'PDF',
                },
              },
            ],
          },
        ],
      },
      {
        data: {
          name: 'Main',
          size: '50mb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'bin',
              size: '50kb',
              type: 'Link',
            },
          },
          {
            data: {
              name: 'etc',
              size: '100kb',
              type: 'Link',
            },
          },
          {
            data: {
              name: 'var',
              size: '100kb',
              type: 'Link',
            },
          },
        ],
      },
      {
        data: {
          name: 'Other',
          size: '5mb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'todo.txt',
              size: '3mb',
              type: 'Text',
            },
          },
          {
            data: {
              name: 'logo.png',
              size: '2mb',
              type: 'Picture',
            },
          },
        ],
      },
      {
        data: {
          name: 'Pictures',
          size: '150kb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'barcelona.jpg',
              size: '90kb',
              type: 'Picture',
            },
          },
          {
            data: {
              name: 'primeng.png',
              size: '30kb',
              type: 'Picture',
            },
          },
          {
            data: {
              name: 'prime.jpg',
              size: '30kb',
              type: 'Picture',
            },
          },
        ],
      },
      {
        data: {
          name: 'Videos',
          size: '1500mb',
          type: 'Folder',
        },
        children: [
          {
            data: {
              name: 'primefaces.mkv',
              size: '1000mb',
              type: 'Video',
            },
          },
          {
            data: {
              name: 'intro.avi',
              size: '500mb',
              type: 'Video',
            },
          },
        ],
      },
    ];
  }

  getFilesystem() {
    return Promise.resolve(this.getFileSystemNodesData());
  }
}
0

There are 0 best solutions below