3

I have simple TurboTable where I show some data, including dates.

<p-table [value]="boxes" #dt>
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th pSortableColumn="Number">
                Number
                <p-sortIcon field="Number"></p-sortIcon>
            </th>
            <th pSortableColumn="DateInserted">
                Interted at
                <p-sortIcon field="DateInserted"></p-sortIcon>
            </th>
        </tr>
        <tr>
            <th>
            <!-- Here is input to filter number -->
            </th>
            <th>
            <!-- Here I want to use Calendar component to select date range -->
            <p-calendar 
                [(ngModel)]="date"
                selectionMode="range"
                [readonlyInput]="true"
                dateFormat="dd.mm.yy"
                (onSelect)="onDateSelect($event)">
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-box>
        <tr [pSelectableRow]="box">
            <td>{{box.Number}}</td>
            <td>{{box.DateInserted | date}}</td>
        </tr>
    </ng-template>
</p-table>

Currently Turbo Table offers only a few match modes to use in filters ( "startsWith", "contains", "endsWith", "equals" and "in"). Is there any option to filter by date or date ranges?

I want to use the Calendar component to select a date range and then filter data by these dates. I am using Date objects (which I present in Table with DatePipe). Now none of these match modes offers option to compare Date objects correctly.

The workaround is to store dates as strings, and then filtering is working. But is is not perfect solution, because it generates problems with converting dates to strings, also date format must be this same everywhere. So maybe there is better option to achieve filtering by date ranges in TurboTable?

Binary Alchemist
  • 1,600
  • 1
  • 13
  • 28
Greggy
  • 617
  • 3
  • 9
  • 20

4 Answers4

11

Component.html

<p-calendar 
    [(ngModel)]="date"
    selectionMode="range"
    [readonlyInput]="true"
    dateFormat="dd.mm.yy"
    (onSelect)="dt.filter($event, 'DateInserted', 'myCustomFilter')">

Component.ts

PrimeNG 8.0.3 and higher

error TS2339: Property 'filterConstraints' does not exist on type 'Table'

filterConstraints was replaced in commit 658507f, with FilterUtils.

import { Table } from 'primeng/table';
//angular 8 import { FilterUtils } from "primeng/api";
//angular 9 import { FilterUtils } from "primeng/utils";
import { FilterUtils } from "primeng/api";
...
@Component({...})
export MyComponent implements OnInit {
    @ViewChild('dt') private _table: Table;
    ngOnInit(){
        FilterUtils['myCustomFilter'] = (value, filter): boolean => {
            return value.getTime() == filter.getTime();
        }
    }
}

PrimeNG 8.0.2 and lower

import { Table } from 'primeng/table';
...
@Component({...})
export MyComponent implements OnInit {
    @ViewChild('dt') private _table: Table;
    ngOnInit(){
        this._table.filterConstraints['myCustomFilter'] = (value, filter): boolean => {
            return value.getTime() == filter.getTime();
        }
    }
}
Gurnard
  • 1,773
  • 22
  • 43
Binary Alchemist
  • 1,600
  • 1
  • 13
  • 28
  • 1
    It is said NOT to import anything from `primeng/primeng`, as that imports the whole library (and then I get errors about chart.js and quill.js). See https://github.com/primefaces/primeng/issues/7769#issuecomment-501220976 – Steve Nov 12 '19 at 18:01
  • 3
    instead: import `{ FilterUtils } from "primeng/api";` – Steve Nov 12 '19 at 18:31
  • The answer here is a good complement for the to replace the content of the filtering function, that method searches within the range: https://stackoverflow.com/questions/50098545/primeng-datatable-date-range-filter – Ivan Lopez May 06 '20 at 00:26
  • this should have been mentioned in the migration guide but it is not https://github.com/primefaces/primeng/wiki/Migration-Guide – Gurnard Sep 28 '21 at 09:21
9

As a workaround, you can add a custom behavior quite simple for the moment.

<p-calendar 
    [(ngModel)]="date"
    selectionMode="range"
    [readonlyInput]="true"
    dateFormat="dd.mm.yy"
    (onSelect)="dt.filter($event, 'DateInserted', 'my')">

Then, in your component you can do this:

import Table from 'primeng/table';
...
@Component({...})
export MyComponent implements OnInit {
    @ViewChild('dt') private _table: Table;
    ngOnInit(){
        this._table.filterConstraints['my'] = (value, filter): boolean => {
            // Make sure the value and the filter are Dates
            return value.getTime() == filter.getTime();
        }
    }
}
Luca Ritossa
  • 1,118
  • 11
  • 22
Cosmin Popescu
  • 190
  • 2
  • 5
7

It appears that, as of PrimeNG 8.0.3 the filterConstraints property on the primeng/table component is no longer available. I've just upgraded from PrimeNG 6 to 8.0.3 and am now seeing the following:

error TS2339: Property 'filterConstraints' does not exist on type 'Table'

on code such as the following:

    this.mydt.filterConstraints['dateRangeFilter'] = (value, filters): boolean => { ...

I know that PrimeNG 8 now has support for date filtering, but this is a date RANGE filter, and we're doing some custom filtering in other places as well. Has the option to implement custom filtering functionality in the PrimeNG table component been removed?

NOTE: I looked at recent changes on GitHub and could see that the filterConstraints was recently refactored out of the Table component. I downgraded PrimeNG to 8.0.2 and all is now working.

Rob Schripsema
  • 103
  • 1
  • 7
  • the docs say that 8 is a direct drop in from 6 and 7 so this should not be a problem. But I have the same issue: https://github.com/primefaces/primeng/wiki/Migration-Guide – Gurnard Sep 28 '21 at 09:20
6

Update : For primeng version 8.04

I just wrote a custom filter, using the answer provided by @binary-alchemist and some other answers after searching for some hours. It worked , so I am sharing the code :

import { FilterUtils } from 'primeng/components/utils/filterutils';
...
...
ngOnInit()
{
    FilterUtils['numberInBetween'] = (value: number, filter: [number, number]) =>
    {
        if (filter === undefined || filter === null)
        {
            return true;
        }

        if (value === undefined || value === null)
        {
            return false;
        }

        return value >= filter[0] && value <= filter[1];
    };
...
...
}
applyFilter(event , dt) {
    // id is the column name , start and end are two numbers , used for filtering id in between them
    dt.filter([start, end], 'id', 'numberInBetween');
}
Luca Ritossa
  • 1,118
  • 11
  • 22
Sourav
  • 365
  • 2
  • 7
  • 17