0
votes

I have created a project in Angular 12 version. Then I have installed the most recent version (11.4.5) of PrimeNG controls in my project. Now I have created a page to use PrimeNG Table with sorting and filtering feature. Bellow the header I have another row to contain the textbox for filtering the data. Now I want, whenever I input any value in the textbox the table rows will automatically be filtered. I don't want to use enter after input any value in the textbox for filtering. But I am facing some compiling error. Here is the code:

<p-table #dt1 [columns]="cols" [value]="products" dataKey="id" styleClass="p-datatable-gridlines p-datatable-striped"
    [paginator]="true" [rows]="5" [showCurrentPageReport]="true"
    currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries" [rowsPerPageOptions]="[5,10,20]">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns" pSortableColumn="{{col.field}}">
                {{col.header}}
                <p-sortIcon field="{{col.field}}"></p-sortIcon>
            </th>
        </tr>
        <tr>
            <th *ngFor="let col of columns" [ngSwitch]="col.field">
                <p-columnFilter *ngSwitchCase="'name'" type="text" field="name" matchMode="contains" [ngModel]="value"
                    (input)="dt1.filter($event.target.value)">
                </p-columnFilter>
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowData let-columns="columns">
        <tr>
            <td *ngFor="let col of columns">
                {{rowData[col.field]}}
            </td>
        </tr>
    </ng-template>
</p-table>

TS file:

import { Component, OnInit } from '@angular/core';
import { Product } from '../_models/product.model';
import { ProductService } from '../_services/product.service';

@Component({
  selector: 'app-dynamic-grid',
  templateUrl: './dynamic-grid.component.html',
  styleUrls: ['./dynamic-grid.component.css']
})
export class DynamicGridComponent implements OnInit {
  products: Product[] = [];
  cols: any[] = [];

  value:any = null;

  constructor(private productService: ProductService) { }

  ngOnInit() {
    this.productService.getProductsSmall().then(data => this.products = data);

    this.cols = [
      { field: 'code', header: 'Code' },
      { field: 'name', header: 'Name' },
      { field: 'category', header: 'Category' },
      { field: 'quantity', header: 'Quantity' }
    ];
  }
}

Model:

export interface Product {
    id?: string;
    code?: string;
    name?: string;
    description?: string;
    price?: number;
    quantity?: number;
    inventoryStatus?: string;
    category?: string;
    image?: string;
    rating?: number;
}

The compile error is :

Error: src/app/dynamic-grid/dynamic-grid.component.html:19:40 - error TS2339: Property 'value' does not exist on type 'EventTarget'.

19 (input)="dt1.filter($event.target.value)"> ~~~~~

src/app/dynamic-grid/dynamic-grid.component.ts:7:16 7 templateUrl: './dynamic-grid.component.html', ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error occurs in the template of component DynamicGridComponent.

Error: src/app/dynamic-grid/dynamic-grid.component.html:19:40 - error TS2531: Object is possibly 'null'.

19 (input)="dt1.filter($event.target.value)"> ~~~~~

src/app/dynamic-grid/dynamic-grid.component.ts:7:16 7 templateUrl: './dynamic-grid.component.html', ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error occurs in the template of component DynamicGridComponent.

** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

enter image description here

Can anyone help me to solve the problem please.

1

1 Answers

1
votes

You get this error as you enable strictTemplate in tsconfig.json.

error TS2339: Property 'value' does not exist on type 'EventTarget'.

Not recommended to disable the settings in tsconfig.json.


Solution

You can write a custom filter applyFilter which receives $event, field and matchMode parameters.

.component.html

<p-columnFilter *ngSwitchCase="'name'" type="text" field="name" matchMode="contains"
  (input)="applyFilter($event, 'name', 'contains')">
</p-columnFilter>

.component.ts

import { ViewChild } from '@angular/core';
import { Table } from 'primeng/table';

@ViewChild('dt1') dt!: Table;

applyFilter($event: any, field: string, matchMode: string) {
  let value = ($event.target as HTMLInputElement)?.value;
  this.dt.filter(value, field, matchMode);
}

Sample Solution on StackBlitz