MenuItem of primeng has a parameter called command that is a function to be executed when its item is clicked. One example of using this is provided in https://www.primefaces.org/primeng/#/steps to give feedback to user.
command: (event: any) => {
this.activeIndex = 0;
this.msgs.length = 0;
this.msgs.push({severity:'info', summary:'First Step', detail: event.item.label});
}
However, I want to use the MenuItem as a column of my Primeng DataTable, like this.
And for this I need to use my menu this way:
<p-column>
<ng-template let-item="rowData"
<p-menu #menu popup="popup" [model]="items"></p-menu>
<button type="button" pButton icon="fa fa-list" label="Show" (click)="menu.toggle($event)"></button>
</ng-template>
</p-column>
To get "item" and the row that I'm clicking and other kind of data.
Using a buttom I can pass item and other data through onClick, but for this I need to create one column for each buttom. And to solve that I want to use Menu with MenuItem from primeng.
The problem is that I can't find any examples passing parameters through a command in MenuItem and I'm not find a way to do it.
How can I accomplish that using MenuItem with DataTable?
If that is not possible, how can I accomplish the same results?
You can have a function that takes rowData and returns contextual MenuItem[]
<p-column>
<ng-template let-item="rowData"
<p-menu #menu popup="popup" [model]="getMenuItemsForItem(item)"></p-menu>
<button type="button" pButton icon="fa fa-list" label="Show" (click)="menu.toggle($event)"></button>
</ng-template>
</p-column>
getMenuItemsForItem(item: MyItem): MenuItem[] {
const context = item;
return [
{ label: 'Label1', icon: 'fa-plus', command: e => this.takeAction(e, context) }
]
}
UPDATE
[model]="getMenuItemsForItem(item)"
can cause performance issues, should be using a binding to an object instead.
[model]="menuItems[item.uniqueKey]"
and then set menuItems object with menu items for each item.
I know this is old but one thing that could prevent having to have NN p-menu
directives in your page would be to call a function from your component on button click instead of (click)="menu.toggle($event)"
and in that function inject the data on each menu item.
I know this is kind of hacky but it's better than to replicate a p-menu
for every table row.
Here is an example :
<p-menu #popupMenu [popup]="true" [model]="menuItems"></p-menu>
<!-- and where you want to open the menu -->
<a *ngIf="itemsMenu" (click)="toggleMenu(popupMenu, $event, rowData)">
<i class="fas fa-chevron-circle-down"></i>
</a>
toggleMenu(menu, event, rowData) {
this.menuItems.forEach((menuItem) => {
menuItem.data = rowData;
});
menu.toggle(event);
}
Regards
I found a way to solve the problem, although I think that it's not the best solution. I hope that those who are with the same problem can find it helpful.
Passing the table item via onClick and populating the menuItems with the callback works.
Sample:
Html
<p-column>
<ng-template let-item="rowData"
<p-menu #menu popup="popup" (onClick)="onClickMenu(item)" [model]="items"></p-menu>
<button type="button" pButton icon="fa fa-list" label="Show" (click)="menu.toggle($event)"></button>
</ng-template>
</p-column>
Typscript
onClickMenu(item: any){
this.items.push({label: 'Option 1',
command: (event: any) => {
doSomething(item);}
});
this.items.push({label: 'Option 2',
command: (event: any) => {
doSomething(item);}
});
this.items.push({label: 'Option 3',
command: (event: any) => {
doSomething(item);}
});
}
JS
this.items = (rowData) => {
return [
{
label: 'Certidão', icon: 'ui-icon-print', command: (event) => {
console.log(rowData);
}
},
{
label: 'Declaração', icon: 'ui-icon-print', command: (event) => {
console.log(rowData);
}
}
];
};
HTML
<p-splitButton label="{{ rowData.nomeColaborador }}" icon="ui-icon-folder" [model]="items(rowData)" >
If you want to pass a rowData you can explicit a function call like this
Another option is to add the current menu rowData to a private variable upon menu selection like so:
<p-menu #menu popup="popup" [model]="items"></p-menu>
<button type="button" class="btn-more" pButton icon="icon-more" label=" " (click)="menu.toggle($event);onClickMenu(rowData);"></button>
public onClickMenu(rowData: any) {
this.currentRowData = rowData;
}
Let me know if there are any repercussions in doing it this way, thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With