angulartypescriptprimeng

Edit row in primeng table by double mouse click


I have primeng table, and it allows to edit rows by clicking on pInitEditableRow button. I want to initiate row editting by double mouse click on that row, any cell of that row. Primeng table doesn't have that functionality out of the box, like with buttons. How to do that? I want to immitate pInitEditableRow button click when I double mouse click on corresponding row.

<p-table [value]="products" dataKey="id" editMode="row" [tableStyle]="{'min-width': '50rem'}">
    <ng-template #header>
        <tr>
            <th style="width:20%">Name</th>
        </tr>
    </ng-template>
    <ng-template #body let-product let-editing="editing" let-ri="rowIndex">
        <tr [pEditableRow]="product">
            <td>
                <p-cellEditor>
                    <ng-template #input>
                        <input
                            pInputText type="text"
                            [(ngModel)]="product.name"
                            required />
                    </ng-template>
                    <ng-template #output>
                        {{product.name}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td>
                <div class="flex items-center justify-center gap-2">
                    <button
                        *ngIf="!editing"
                        pButton
                        pRipple
                        type="button"
                        pInitEditableRow
                        icon="pi pi-pencil"
                        (click)="onRowEditInit(product)"
                        text
                        rounded
                        severity="secondary"
                    ></button>
                    <button
                        *ngIf="editing"
                        pButton
                        pRipple
                        type="button"
                        pSaveEditableRow
                        icon="pi pi-check"
                        (click)="onRowEditSave(product)"
                        text
                        rounded
                        severity="secondary"
                    ></button>
                    <button
                        *ngIf="editing"
                        pButton
                        pRipple
                        type="button"
                        pCancelEditableRow
                        icon="pi pi-times"
                        (click)="onRowEditCancel(product, ri)"
                        text
                        rounded
                        severity="secondary"
                    ></button>
                </div>
            </td>
        </tr>
    </ng-template>
</p-table>

Solution

  • Original Answer

    Not sure that a “double-click-to-edit” feature is supported by PrimeNG out of the box.

    However you can get your behavior by simply using a template reference (let's say dt) and a ViewChild.

    What you need to do is simply to:

    1. Add a template reference (#dt in the example below) to your p-table
    2. Use a ViewChild to access your table.
    3. Add a custom event listener (onRowDblClick in the example below) for the (dblclick) event on each tr element .
    4. Inside your event listener use this.dt.initRowEdit(product);

    Example:

    HTML

    <p-table
      #dt
      [value]="products"
      dataKey="id"
      editMode="row"
      [tableStyle]="{ 'min-width': '50rem' }"
    >
      <ng-template #header>
        <tr>
          <th style="width:20%">Name</th>
        </tr>
      </ng-template>
    
      <ng-template #body let-product let-editing="editing" let-ri="rowIndex">
        <!-- Make sure to add (dblclick): -->
        <tr [pEditableRow]="product" (dblclick)="onRowDblClick(product)">
          <td>
            <p-cellEditor>
              <ng-template #input>
                <input pInputText type="text" [(ngModel)]="product.name" required />
              </ng-template>
              <ng-template #output>
                {{ product.name }}
              </ng-template>
            </p-cellEditor>
          </td>
          <td>
            <div class="flex items-center justify-center gap-2">
              <button
                *ngIf="!editing"
                pButton
                pRipple
                type="button"
                pInitEditableRow
                icon="pi pi-pencil"
                (click)="onRowEditInit(product)"
                text
                rounded
                severity="secondary"
              ></button>
              <button
                *ngIf="editing"
                pButton
                pRipple
                type="button"
                pSaveEditableRow
                icon="pi pi-check"
                (click)="onRowEditSave(product)"
                text
                rounded
                severity="secondary"
              ></button>
              <button
                *ngIf="editing"
                pButton
                pRipple
                type="button"
                pCancelEditableRow
                icon="pi pi-times"
                (click)="onRowEditCancel(product, ri)"
                text
                rounded
                severity="secondary"
              ></button>
            </div>
          </td>
        </tr>
      </ng-template>
    </p-table>
    

    TS

    import { Component, ViewChild } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { InputTextModule } from 'primeng/inputtext';
    import { ButtonModule } from 'primeng/button';
    import { Table, TableModule } from 'primeng/table';
    import { MessageModule } from 'primeng/message';
    import { CommonModule } from '@angular/common';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [
        CommonModule,
        InputTextModule,
        ButtonModule,
        TableModule,
        MessageModule,
        FormsModule,
      ],
      templateUrl: './app.component.html',
      styleUrl: './app.component.css',
    })
    export class AppComponent {
      @ViewChild('dt') dt!: Table;
    
      products = [
        { id: 1, name: 'Laptop' },
        { id: 2, name: 'Wireless Mouse' },
        { id: 3, name: 'Smartphone' },
        { id: 4, name: 'Smart TV' },
        { id: 5, name: 'Bluetooth Headphones' },
        { id: 6, name: 'Gaming Console' },
        { id: 7, name: 'Smartwatch' },
        { id: 8, name: 'Tablet' },
      ];
    
      onRowDblClick(product: any) {
        // Enable editing the row
        this.dt.initRowEdit(product);
    
        // this.onRowEditInit(product);
      }
    
      onRowEditInit(product: any) {
        // ...
      }
    
      onRowEditSave(product: any) {
        // ...
      }
    
      onRowEditCancel(product: any, index: number) {
        // ...
      }
    }
    

    You can find a minimal working example here

    Update

    PrimeNG supports table editing through the directives pEditableColumn, pEditableColumn, pInitEditableRow and many more. Here's the dedicated section in the docs.

    One minor thing to note is that, by using the aforementioned directives, editing is enabled by clicking one time over an element instead of double clicking.