Reputation: 1678
I am using PrimeNg's context menu v6.0.1, the problem is the documentation is not clear and I cannot find it over the web as well on how to pass data to command function e.g.:
I have 10 objects rendered on screen and context menu is attached to all of these objects, now if I click on menu item I want to get the id of the target object on which the context menu is rendered, how can this be accomplished?
<div id="block-container" *ngFor="let block of blocks">
<!-- where to attach this block object ??? -->
<p-contextMenu appendTo="body"
[target]="blockContextMenu"
[model]="contextMenuItems">
</p-contextMenu>
<div #blockContextMenu>
Some implementation...
</div>
</div>
and following is my items model:
this.contextMenuItems = [
{
label: 'Trip Details',
command: (event) => {
// event doesn't contain anything useful,
// and only has the clicked menu item specific information.
}}
];
Upvotes: 6
Views: 6236
Reputation: 3104
You'll need to bind the a model to the context menu, just like in the documentation, but then programmatically change the model & open the menu.
1. Remove the target
attribute from p-contextMenu
- this would prevent out-of-the-box menu toggle mechanism.(<p-contextMenu #contextMenu appendTo="body" [model]="contextMenuItems"></p-contextMenu>
)
2. Instead of referencing (<div #blockContextMenu></div>
), use event binding (<div (contextmenu)="openContextMenu($event, dataYouNeedToPass)"></div>
)
3. In your component, use @ViewChild
to get access to the context menu and declare an empty model:
@ViewChild('contextMenu', { static: false }) contextMenu: ContextMenu;
contextMenuItems: MenuItem[] = [];
4. Add the openContextMenu
function to programmatically change the model & open the context menu:
openContextMenu(event: MouseEvent, dataYouNeedToPass: any): void {
this.contextMenuItems = [{
label: 'Action One',
command: (event) => this.doActionOne(dataYouNeedToPass)
},
{
label: 'Action Two',
command: (event) => this.doActionTwo(dataYouNeedToPass)
}];
this.documentActionContextMenu.show(event);
event.stopPropagation();
}
Upvotes: 1
Reputation: 344
As the "Id's" are unique you need only pass it with the command() function:
https://primeng-panelmenu-return-id.stackblitz.io
items: MenuItem[];
ngOnInit() {
this.items = [
{ label: "Rename", id: "1", command: () => this.onClickMenuItem("1") },
{ label: "Delete", id: "2", command: () => this.onClickMenuItem("2") },
{ label: "Add", id: "3", command: () => this.onClickMenuItem("3") }
];
}
onClickMenuItem(id: string) {
console.log(id);
}
Upvotes: 0
Reputation: 1083
We can get data on the PrimeNG context Menu Item click by just pushing data to command property callback function.
Below example code is also an example of the dynamic context menu creation with the Nth level.
For Example -
[
{
"ID": 1,
"TITLE": "parent1",
"SUBMENU": [
{
"ID": 2,
"SUBMENU": [
{
"ID": 3,
"SUBMENU": [
{
"ID": 4,
"TITLE": "Child 1"
}
]
},
{
"ID": 13,
"SUBMENU": [
{
"ID": 5,
"TITLE": "Child 3"
}
]
},
{
"ID": 6,
"SUBMENU": [
{
"ID": 7,
"SUBMENU": [
{
"ID": 8,
"TITLE": "Child 4"
}
]
},
{
"ID": 9,
"SUBMENU": [
]
}
],
},
{
"ID": 10,
"SUBMENU": [
{
"SUBMENU": [
]
}
]
}
],
}
],
},
{
"ID": 11,
"TITLE": "parent2",
"SUBMENU": [
{
"ID": 12,
"TITLE": "Child 4"
}
],
}
]
From the above JSON, I created the PrimeNG context menu Items.
createContextMenuRecursive(object: any[]): MenuItem[] {
if (object) {
let menuList: MenuItem[] = [];
for (var i = 0; i < object.length; i++) {
if (object[i].ITEMS && object[i].ITEMS.length > 0) {
let returnedList = this.createContextMenuRecursive(object[i].ITEMS);
menuList.push(this.createMenuItem(object[i], returnedList));
}
else {
menuList.push(this.createMenuItem(object[i]));
}
}
return menuList;
}
}
The below function is used to create the PrimeNG context menu Item, where parameter data: any represents the data we need to use in command function.
createMenuItem(data: any, menuItems: MenuItem[] = []): MenuItem {
if (menuItems.length > 0) {
return { label: data.TITLE, items: menuItems, command: (event) => this.docGridContextMenuItemClick(event, data) };
}
else {
return { label: data.TITLE, command: (event) => this.docGridContextMenuItemClick(event, data) };
}
}
Context menu item click event handler where we use the data.
docGridContextMenuItemClick(event: any, data: any) {
console.log(JSON.stringify(data));
}
Upvotes: 0
Reputation: 1107
@ViewChild('copyMenu') copyMenu: ContextMenu;
onLinkRightClicked(content: string, e: any): void {
if (this.copyMenu) {
let model: MenuItem[] = [];
model.push({ label: 'Action', command: (event) => this.doAction(content) });
this.copyMenu.model = model;
this.copyMenu.show(e);
}
}
doAction(content){
// here
}
<div #blockContextMenu (contextmenu)="onLinkRightClicked(content, $event)">
Some implementation...
</div>
<p-contextMenu appendTo="body" #targetContextMenu>
</p-contextMenu>
Upvotes: 4
Reputation: 6568
For a proper implementation of context menu with primeng you need to add
[contextMenu]="cm"
in an element which you want to show, for example, you want context menu over your div you need to mention
<div id="block-container" *ngFor="let block of blocks" [contextMenu]="cm"></div>
also in the p-contextMenu element, you need to do mentioned the variable of context menu from your div like
hope this helps.
Upvotes: 0