4

So I have a table with data that gets populated throughout the use of the application. When a user clicks on a row, the row is highlighted and that row's data is populated beneath the table. I just want to disable the option of the user to deselect a row (this is done by clicking on the row again).

The code:

<p-table #purchaseOrdersList
         [value]="purchaseOrders"
         selectionMode="single"
         [(selection)]="selectedPurchaseOrder"
         (onRowSelect)="onRowSelect($event)"
          >

<ng-template pTemplate="header">
    <tr>
      <th class="supplier-number-col">Supplier Number</th>
      <th class="supplier-name-col">Supplier Name</th>
      <th class="supplier-phone-col">Supplier Phone</th>
    </tr>
  </ng-template>

  <ng-template pTemplate="body" let-purchaseOrder>
    <tr [pSelectableRow]="selectedRow">
      <td>{{purchaseOrder.supplierNumber}}</td>
      <td>{{purchaseOrder.supplierName}}</td>
      <td>{{purchaseOrder.supplierPhoneNumber}}</td>
    </tr>
  </ng-template>

</p-table>
Antikhippe
  • 6,316
  • 2
  • 28
  • 43
Boris
  • 475
  • 5
  • 12

4 Answers4

6

I was having the exact same question, and came up with two solutions: a very simple one, and a slightly more complex solution:

Simple solution:

tr.ui-state-highlight {
    pointer-events: none;
}

This will prevent any selected row from being clicked again, thereby preventing deselection.

However, this will also prevent double-clicking the row. So if you need double-clicking, use the following solution:

Slighty more complex solution:

Add the following attribute to the p-table: (onRowUnselect)="cancelUnselect($event)", and then in your component do:

private _selectedPurchaseOrder: any;

get selectedPurchaseOrder() {
    return this._selectedPurchaseOrder;
}

set selectedPurchaseOrder(value: any) {
    if (value) {
        this._selectedPurchaseOrder = value;
    } else {
        this.purchaseOrdersList.selection = this._selectedPurchaseOrder;
    }
}

cancelUnselect(event) {
        this.purchaseOrdersList.selection = event.data;
}

This will prevent deselection of a row in all cases, and double-clicking is still possible.

HammerNL
  • 1,689
  • 18
  • 22
  • How can I access purchaseOrdersList? I recognized that the table is marked with #purchaseOrdersList but how can I access it in the ts code? – max Jun 22 '18 at 11:02
  • 1
    @max That is a new question in itself, but you should add the ViewChild annotation to a local variable, like this: @ViewChild('purchaseOrdersList') purchaseOrdersList: any – HammerNL Jun 24 '18 at 19:28
  • Great answers, though there are some drawbacks, especially for the first one. By turning off pointer-events, sorting gets affected. You can click the sort button and see the rows sort out in ascending order, but you can't click it again. As for the second one, as I've encountered, if the row is clicked again, the highlight is retained, but if you have pagination and page over and come back to the original page, the highlighting is gone (if you have a fix or you believe there's a mistake on my end, feel free to reach me out) . – Hisham Ahamad Oct 09 '18 at 13:11
2

This can now be solved through metaKeySelection option. Setting it to true will allow row deselection only when the meta key is held.

Boris
  • 475
  • 5
  • 12
  • This is not really a solution; it's still possible to deselect the row. Also, it won't work on touch devices as metaKeySelection is turned off automatically there. – HammerNL May 30 '18 at 09:15
  • I found a proper solution! Check out my answer. – HammerNL May 30 '18 at 10:17
2

I'm using PrimeNG 9.1 and had to adapt HammerNL's solution as follows to prevent row deselection:

cancelUnselect(event) {
    this.purchaseOrdersList.selection = event.data;
    this.purchaseOrdersList.selectionChange.emit(event.data);
    this.purchaseOrdersList.updateSelectionKeys();
  }

updateSelectionKeys is necessary if you use the table's "dataKey" property

Stephanie
  • 508
  • 5
  • 14
0
<p-table #purchaseOrdersList
         [value]="purchaseOrders"
         selectionMode="single"
         [(selection)]="selectedPurchaseOrder"
         (onRowSelect)="onRowSelect($event)"  (onRowUnselect) = "onRowUnselect()"
          >

<ng-template pTemplate="header">
    <tr>
      <th class="supplier-number-col">Supplier Number</th>
      <th class="supplier-name-col">Supplier Name</th>
      <th class="supplier-phone-col">Supplier Phone</th>
    </tr>
  </ng-template>

  <ng-template pTemplate="body" let-purchaseOrder>
    <tr [pSelectableRow]="selectedRow">
      <td>{{purchaseOrder.supplierNumber}}</td>
      <td>{{purchaseOrder.supplierName}}</td>
      <td>{{purchaseOrder.supplierPhoneNumber}}</td>
    </tr>
  </ng-template>

</p-table>

In The .ts file you can use as

onRowUnselect() {

        var selectedCount = this.selectedPurchaseOrder.length;

        //  this.isDeleteShow = (selectedCount >0);
        $(".PATotalRowsSelected").html("(" + selectedCount + " selected)");

    }
BHAVIK
  • 890
  • 7
  • 35