I have a PrimeNG v12.2 p-table
component abbreviated as follows:
<p-table
[(selection)]="selectedMessages"
selectionMode="multiple">
I need to programmatically select the row the user just clicked on. I figured I would just push a new object to selectedMessages
in the click, but it does not work. The object is pushed, but nothing remains selected.
I need to handle the right-click. The row is defined as:
<tr (contextmenu)="clickMessage(message)">
The event is handled with:
clickMessage(mail: MailboxItem): void {
this.selectedMessages.push(mail);
}
The member is initialized to empty:
selectedMessages: MailboxItem[] = [];
My event fires properly, the object goes from empty ([]
) to having one MailboxItem
in it, but no table rows are selected.
CodePudding user response:
I'm sorry, I can't test this now, but I guess you should put the id of your MailboxItem object as "dataKey" in your table.
For instance, if your mail rows are getting value from an array like this:
mailsArray: MailboxItem[] =
[
{
myId=1;
from="Patrick";
message="Blah,blah,bla..";
},
{
myId=2;
from="Swaiczwe";
message="Lorem blahblah etceterabla..";
}
];
then your table should had a dataKey attibute like this:
<p-table
[(selection)]="selectedMessages"
selectionMode="multiple"
[value]="mailsArray"
dataKey="myId"
>
And finally, your method clickMessage() should be like this:
clickMessage(mail: MailboxItem): void {
this.selectedMessages.push(mail.myID);
}
You should put also something similar to this in yours header and body templates (sorry, but you didn't show how you have it, so it's approximate):
<ng-template pTemplate="header">
<tr [pSelectableRow]="mail">
<th>Id</th>
<th>From</th>
<th>Message</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-mail let-rowIndex="rowIndex">
<tr [pSelectableRow]="mail" [pSelectableRowIndex]="rowIndex">
<td>{{mail.myId}}</td>
<td>{{mail.from}}</td>
<td>{{mail.message}}</td>
</tr>
</ng-template>
P.S: Also try changing
<ng-template pTemplate="header">
<tr [pSelectableRow]="mail">
just to a 'simple' , like this:
<ng-template pTemplate="header">
<tr>
CodePudding user response:
The issue here is that Angular change detection only occurs when the array bound to [(selection)]
is modified.
The solution is to re-assign to the array itself which will trigger change detection and properly select the row:
this.selectedMessages = [...this.selectedMessages, mail];
In my use-case we want to de-select all rows except the one being right-clicked on, so it is simply:
this.selectedMessages = [ mail ];