2

I have a editable PrimeNG table bound with reactive forms (not with ngtemplate). If I click edit of a single row, all rows turns into edit mode. Here is the image explaining my issue.

enter image description here

The prob is with the dataKey used with PrimeNg Edit table. I have no clue what to bind with dataKey, when using reactive forms.

Here is the minimal code explaining the issue.

HTML.ts

<div class="card">
    <div class="card-header">
        <h5>Reactive Forms with PrimeNg Table</h5>
    </div>
    <div class="card-body">
        <form [formGroup]="employeeForm">
            <p-table [value]="tableRowArray.controls" [responsive]="true" dataKey="name" editMode="row"
                responsiveLayout="scroll" dataKey="name"> <!--dataKey is set wrongly-->
                <ng-template pTemplate="header">
                    <tr>
                        <ng-container *ngFor="let col of columns">
                            <td>{{col}}</td>
                        </ng-container>
                    </tr>
                </ng-template>
                <ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex" let-editing="editing">
                    <ng-container formArrayName="tableRowArray">
                        <tr [formGroupName]="rowIndex" [pEditableRow]="rowData">
                            <td style="text-align:center">
                                <button *ngIf="!editing" pButton pRipple type="button" pInitEditableRow icon="pi pi-pencil"  class="p-button-rounded p-button-text"></button>
                                <button *ngIf="editing" pButton pRipple type="button" pSaveEditableRow icon="pi pi-check"  class="p-button-rounded p-button-text p-button-success mr-2"></button>
                                <button *ngIf="editing" pButton pRipple type="button" pCancelEditableRow icon="pi pi-times"  class="p-button-rounded p-button-text p-button-danger"></button>
                            </td>
                            <td>
                                <p-cellEditor>
                                    <ng-template pTemplate="input"></ng-template>
                                    <ng-template pTemplate="output">
                                        <input type="text" class="form-control form-control-sm"
                                            formControlName="name" />
                                        <div class="text-danger"
                                            *ngIf="rowData.get('name').errors && (rowData.get('name').dirty || rowData.get('name').touched)">
                                            <div *ngIf="rowData.get('name').errors?.required">Name is Required</div>
                                        </div>
                                    </ng-template>
                                </p-cellEditor>
                            </td>                                                  
                        </tr>
                    </ng-container>
                </ng-template>
            </p-table>
        </form>
    </div>
    <div class="card-footer">
        <button type="button" class="btn btn-primary btn-sm pull-left" (click)="addNewRow()">Add Row</button>
        <button type="button" class="btn btn-success btn-sm pull-right" title="Save">Save</button>
    </div>
</div>

Component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-add-employee',
  templateUrl: './add-employee.component.html'
})
export class AddEmployeeComponent implements OnInit {

  employeeForm: FormGroup;
  columns: string[];

  constructor(private formBuilder: FormBuilder) {
    this.columns = ["Edit", "Name"];
  }

  ngOnInit(): void {
    this.createForm();
  }

  get tableRowArray(): FormArray {
    debugger;
    return this.employeeForm.get('tableRowArray') as FormArray;
  }

  addNewRow(): void {
    this.tableRowArray.push(this.createTableRow());
  }

  onDeleteRow(rowIndex:number): void {
    this.tableRowArray.removeAt(rowIndex);
  }

  /**
   * Initializes the Form & by default adds an empty row to the PRIMENG TABLE
   */
  private createForm(): void {
    this.employeeForm = this.formBuilder.group({
      tableRowArray: this.formBuilder.array([
        this.createTableRow()
      ])
    });
  }

  /**
   * Returns the FormGroup as a Table Row
   */
  private createTableRow(): FormGroup {
    return this.formBuilder.group({
      name: new FormControl(null, { validators: [Validators.required, Validators.minLength(3), Validators.maxLength(50)] })   
    });
  }

}
Anil P Babu
  • 1,235
  • 3
  • 26
  • 47
  • 1
    Does this answer your question? [Editable Row Issue on primeNG table](https://stackoverflow.com/questions/59223622/editable-row-issue-on-primeng-table) – Stephanie Sep 02 '22 at 07:37
  • Think that question does not use Reactive forms (even though I Copied images from it :D ) – Anil P Babu Sep 02 '22 at 18:13

1 Answers1

1

You have dataKey set twice in your p-table tag. Apart from that I think you should assign an ID to your row data so that you can use that as a dataKey. I think you will need it for saving your row data anyway.

Stephanie
  • 508
  • 5
  • 14
  • Nice find! It was complicated for me to use reactive forms with tables. So I opted it out. I am not trying this. Sorry. I can approve this answer if you show me a working solution. – Anil P Babu Sep 02 '22 at 18:10
  • @AnilPBabu , were u able to figure this out? I am currently stuck with the same issue. What should we give as dataKey when going for formarray in primeng table. By just giving the control name, which is unique seems not working for me. – Aeverlite Jan 10 '23 at 10:20
  • @Aeverlite i am sry. I dropped the plan to use reactforms and did without it. – Anil P Babu Jan 11 '23 at 17:19