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)
<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());
}
}