'Primeng table p-table,set conditional column editable

I am using Primeng p-table control in my angular 7 application. Below is the html code I am using:

<p-table [value]="data" [reorderableColumns]="'true'" [columns]="cols">
<ng-template pTemplate="header" let-columns>
    <tr>

        <th *ngFor="let col of columns" pReorderableColumn>
            {{col.header}}
        </th>
    </tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
    <tr>
        <td  [pEditableColumn] *ngFor="let col of columns" [ngSwitch]="col.field">
            <p-cellEditor  *ngSwitchCase="'TYPE'">
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
                <p-cellEditor *ngSwitchCase="'CEPCODE'">
                        <ng-template pTemplate="input">
                            <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                        </ng-template>
                        <ng-template pTemplate="output">
                            {{rowData[col.field]}}
                        </ng-template>
                    </p-cellEditor>
                    <p-cellEditor *ngSwitchCase="'HRS'">
                            <ng-template pTemplate="input">
                                <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                            </ng-template>
                            <ng-template pTemplate="output">
                                {{rowData[col.field]}}
                            </ng-template>
                        </p-cellEditor>

        </td>

    </tr>
</ng-template>

On Running application table looks like below: enter image description here

In my above table Type column is not editable and all other columns are editable. I want to know how we can set [pEditableColumn] for td dynamically(if column is type then do not set [pEditableColumn])



Solution 1:[1]

Finally I found the below workarround(inline editing working with cell navigation)

<p-table  (sortFunction)="customSort($event)" [customSort]="true" [scrollable]="true" scrollHeight="650px" class="png-table"
[value]="data" [reorderableColumns]="'false'" [resizableColumns]="'false'" [columns]="cols">
<ng-template pTemplate="header" let-columns>
    <tr>
        <th *ngFor="let col of columns" [pSortableColumn]="col.field" [style.width.px]="getColumnWidth(col)" [hidden]="col.hide"
            pResizableColumn pReorderableColumn [class]="col.filter?'sortable':'non-sortable'">
            {{col.headerName}}
            <p-sortIcon [field]="col.field"></p-sortIcon>

        </th>
    </tr>
    <tr class="filter-row" *ngIf="1==2">
        <th *ngFor="let col of columns" [hidden]="col.hide">
            <input class="filter-input" *ngIf="col.filter" pInputText type="text" (input)="dt.filter($event.target.value, col.field, 'contains')">
        </th>
    </tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
    <tr>
        <ng-container *ngFor="let col of columns" [ngSwitch]="col.type">
            <td *ngSwitchCase="'del'" [style.width.px]="getColumnWidth(col)">
                <i class="fa fa-close delete-icon g-act-icon" (click)='deleteRow()'></i>
            </td>
            <td *ngSwitchCase="'edit'" [style.width.px]="getColumnWidth(col)">
                <i class="fa fa-edit edit-icon g-act-icon" (click)='deleteRow()'></i>
            </td>
            <td *ngIf="!col.hide && col.type=='type'"  [style.width.px]="getColumnWidth(col)">
                {{rowData[col.field]}}
            </td>
            <td [pEditableColumn] *ngSwitchCase="'cep'" [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <p-inputMask (keyup)="onEnterCEP()" [(ngModel)]="rowData[col.field]" mask="aaaaaa-999-999"></p-inputMask>

                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td [hidden]="col.hide" *ngSwitchCase="'cb'" [style.width.px]="getColumnWidth(col)">
                {{rowData[col.field]}}
            </td>
            <td *ngIf="!col.hide && col.type=='act'" [pEditableColumn]  [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td  [pEditableColumn] *ngIf="!col.hide && col.type=='com'" [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td [pEditableColumn] *ngIf="!col.hide && col.type=='tsk'" [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td  [pEditableColumn] *ngIf="!col.hide && col.type=='sco'" [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td [pEditableColumn] *ngSwitchCase="'hrs'" [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" >
                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
            <td [hidden]="col.hide" [pEditableColumn] *ngSwitchCase="'des'" [style.width.px]="getColumnWidth(col)">
                <p-cellEditor>
                    <ng-template pTemplate="input">
                        <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                    </ng-template>
                    <ng-template pTemplate="output">
                        {{rowData[col.field]}}
                    </ng-template>
                </p-cellEditor>
            </td>
        </ng-container>
    </tr>
</ng-template></p-table>

Solution 2:[2]

This feature was there in the earlier version of primeNG and was easy to implement, however, you can use the below approach.

You can add one property to column configuration like col.editable

Component.ts

import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  cols = [];
  data = [];
  constructor() {
    this.cols = [
      { header: "TYPE", field: "TYPE", editable: false },
      { header: "CEPCODE", field: "CEPCODE", editable: true },
      { header: "HRS", field: "HRS", editable: true }
    ];

    this.data = [{ HRS: "HRS1", TYPE: "OMEGA", CEPCODE: "YTMMETRE" }];
  }
}

Based on that you can change the template when you are dynamically adding the template. component.html

<p-table [value]="data" [reorderableColumns]="'true'" [columns]="cols">
<ng-template pTemplate="header" let-columns>
    <tr>

        <th *ngFor="let col of columns" pReorderableColumn>
            {{col.header}}
        </th>
    </tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
    <tr>
        <td *ngFor="let col of columns" [pEditableColumn] [ngClass]="{'disable-td' : !col.editable}" >
              <div *ngIf="!col.editable">
                {{rowData[col.field]}}
              </div>
              <p-cellEditor *ngIf="col.editable">
                      <ng-template pTemplate="input">
                          <input pInputText type="text" [(ngModel)]="rowData[col.field]" required>
                      </ng-template>
                      <ng-template pTemplate="output">
                          {{rowData[col.field]}}
                      </ng-template>
              </p-cellEditor>
        </td>
    </tr>
</ng-template>
</p-table>

component.scss

.disable-td{
    pointer-events: none;
}

working stackblitz

Template code removed for brevity!

Solution 3:[3]

There is actually an undocumented pEditableColumnDisabled boolean directive that can be used to control if a cell is editable or not.

Source: https://github.com/primefaces/primeng/blob/v12.2.3/src/app/components/table/table.ts#L3337

Using it would be something like <td pEditableColumn [pEditableColumnDisabled]="!col.editable" *ngFor="let col of columns" [ngSwitch]="col.field">.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Suresh Negi
Solution 2 Abhinav Kumar
Solution 3 Brad C