Primeng: Custom Filter Elements for DataTable

Created on 12 Apr 2016  路  31Comments  路  Source: primefaces/primeng

Add support to place custom content like dropdown, calendar to the filter field of datatable as an alternative to default text-fields.

new feature

Most helpful comment

it is beta14, we really need this feature..

All 31 comments

Will this be added in near future? this is must have feature

Much appreciated this feature. +1

I would like to leave some implementation suggestions:

  • Create a template option to filter, similar to what is already there for the columns of the DataTable and allow your events are intercepted and processed by custom listeners, which can be set up any type of filter that may be necessary, in addition to those already mentioned (dropdown, calendar), for example, between (two inputs), bool (checkbox), etc.
  • Allow the object that keeps the DataTable filters can be manipulated by filters outside the DataTable, for example, you have a filter field to a value that is not present in the columns of the DataTable (Example: checkbox active item).

If you just want a custom filter (with the standard textbox) a workaround I am using is to set the table to [lazy]="true" you then implement a refresh method yourself, example:

// template

<p-datatable ... [value]="entities" [lazy]="true" [totalRecords]="totrows" (onLazyLoad)="refresh($event, table)"...

// component

...
public entities: any[];
public totrows: number;
public originals: any[];

loadedFromServer(entities: any[]) {
    this.originals = entities;
    this.entities = entities;
}

refresh(e: any, table: DataTable) {
    const global = table.globalFilter ? table.globalFilter.value : null;
    this.entities = Sorters.datatableSort(this.originals, e.sortField, e.sortOrder);
    this.entities = !e.filters ? 
        this.entities : 
        SmartFilter.filter(this.entities, e.filters, global);
    this.totrows = this.entities.length;
    if (e.rows) { this.entities = this.entities.slice(e.first, (e.first + e.rows)); }
  }  
...

+1000 very needed

We've done it for PrimeFaces before and will definitely work on it for PrimeNG for beta8. http://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml

It's beta8, did you manage to implement it?

Any updates on the status of this?

Still nothing in beta11 :disappointed:

We're trying to figure out the best way to do this.

:up:

it is beta14, we really need this feature..

Is this feature also going to be part of beta 16 next week?

Is this possible to set a custom template for filter? It will be more flexible, and allow to add dropdowns, multiselect, and also we can set "clear filter" button for each filter.

Still need this feature.

We'll work on it for 1.0.2.

screen shot 2016-12-07 at 14 45 29

@cagataycivici have you all implemented the feature where you can put a calendar in a data table? Still do not see that in the documentation and have tried to look everywhere for this implementation.

I want to format a new Date() field. But i also can't set a dynamic template for that.

I would like to use the Range slider but the $event.value could not be a list ?

@mcmack25 @MTechDE @Biman54 this is my solution for filtering with CalendarModule (p-calendar) DataTableModule (p-datatable) or filter format YYYY-MM-DD datatable primeng

  1. import calendar module primeng where use datatable module
  2. declare #dt in template my example datatable name customerPurchaseOrderMembershipInvoices
    <p-dataTable [value]="customerPurchaseOrderMembershipInvoices" sortMode="multiple" [rows]="10" [paginator]="true" [pageLinks]="3" [rowsPerPageOptions]="[5,10,20]" [globalFilter]="gb" #dt>
  3. declare style for overflow visible , declare filterMachMode="startsWith" (this is important for functions onSelect and Onblur of Calendar Callbacks) , format dateFormat="yy-mm-dd", Declare calendar events with own functions onBlurCalendarInputPrimeng and onSelectCalendarInputPrimeng there params $event(event handler calendar module),dt (dt references datatable object),col.field (references field of datatable is field="payment_date" ),col.filterMatchMode (references mode of mach mode is startsWith )

<p-column field="payment_date" header="Fecha de pago" [style]="{'width':'180px','overflow':'visible'}" [filter]="true" filterMatchMode="startsWith" [sortable]="true"> <template pTemplate="filter" let-col> <div> <p-calendar [(ngModel)]="dateFilter" [locale]="es" dateFormat="yy-mm-dd" (onBlur)=onBlurCalendarInputPrimeng($event,dt,col.field,col.filterMatchMode) (onSelect)="onSelectCalendarInputPrimeng($event,dt,col.field,col.filterMatchMode)" #calendar></p-calendar> </div> </template> <template let-col let-customerPurchaseOrderMembreship="rowData" pTemplate="body"> <span>{{customerPurchaseOrderMembreship[col.field]}}</span> </template> </p-column>

  1. vars declare in component in component init datatable and optional i declere array with spanish lang
    dateFilter: Date; ngOnInit(): void { this.es = { firstDayOfWeek: 1, dayNames: ["domingo", "lunes", "martes", "mi茅rcoles", "jueves", "viernes", "s谩bado"], dayNamesShort: ["dom", "lun", "mar", "mi茅", "jue", "vie", "s谩b"], dayNamesMin: ["D", "L", "M", "X", "J", "V", "S"], monthNames: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], monthNamesShort: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] }}
  1. method in component init datatable onSelectCalendarInputPrimeng
    onSelectCalendarInputPrimeng(event: any, dt: any, colField: any, colFilterMatchMode: any) { console.log('entro on select') let stringDateFilter = this.dateFilter.toISOString().slice(0, 10); dt.filter(stringDateFilter, colField, colFilterMatchMode);}

  2. method backend in component init datatable onBlurCalendarInputPrimeng
    onBlurCalendarInputPrimeng(event: any, dt: any, colField: any, colFilterMatchMode: any) { console.log('entro a blur') let beforeDateFilter = this.dateFilter; if (!this.dateFilter || this.dateFilter == null) { console.log('entro a reset') dt.filter('', colField, colFilterMatchMode); } this.dateFilter = beforeDateFilter; }

  3. for test create class customerPurchaseOrderMembershipInvoice with properties payment_date , create array of class customerPurchaseOrderMembershipInvoice name customerPurchaseOrderMembershipInvoices, add object with value of payment_date format YYYY-MM-DD HH24:MM

How define the filter in column with a specific width?

is there any solution for custom filters in primeNg table ?
any update ?

How to disable default filtering in PrimeNg DataTable ?

PrimeNG DataTable has an option [filter]="true" which enables an input on column header used to filter data.
But we need globally flag to enable/disable filter of PrimeNg DataTable .

Is is possible to customize DataTable filter? I have a requirement to filter data from out side of the or we can say that from a different component like a left rail.

I found a way to implement the custom filter constraints to dataTable. I don't know whether it is the optimal way to do it. As of now we have only "startsWith", "endsWith", "in", "equals", "notEquals" and "contains". But we had a requirement for "between".

The implementation was like this...

export class Component implements AfterViewChecked {
@ViewChild('dt') dataTable: DataTable;


ngAfterViewChecked() {
    // Add custom dataTable filter constraints
    if (this.dataTable !== undefined) {

      const customFilterConstraints = this.dataTable.filterConstraints;
      customFilterConstraints['between'] = this.between; //between filter functionality
      this.dataTable.filterConstraints = customFilterConstraints;
    }
  }

//between filter takes two values (from and to date)
 onSelectCalendar(dt: any, colField: any, colFilterMatchMode: any) {
    dt.filter([this.fromDateFilter, this.toDateFilter], colField, colFilterMatchMode);
  }
}

And in template
<p-column [filter]="true" [style]="col.Style" filterMatchMode="between">
            <ng-template pTemplate="filter" let-col>
                <div class="calendarFilter">
                    Between <p-calendar [(ngModel)]="fromDateFilter" appendTo="body" utc="true" dataType="string" [showIcon]="true" dateFormat="yy-mm-dd" (onBlur)="onBlurCalendar(dt, col.field, col.filterMatchMode)" (onSelect)="onSelectCalendar(dt,col.field, col.filterMatchMode)" styleClass="ui-column-filter"></p-calendar>
                    and <p-calendar [(ngModel)]="toDateFilter" appendTo="body" utc="true" dataType="string" [showIcon]="true"  dateFormat="yy-mm-dd" (onBlur)="onBlurCalendar(dt, col.field,col.filterMatchMode)" (onSelect)="onSelectCalendar(dt,col.field,col.filterMatchMode)" styleClass="ui-column-filter"></p-calendar>
                </div>
            </ng-template>
        </p-column>



_Please someone give feedback for this._

@cagataycivici : Can i know why this is closed?

@ramyapkumar Where does the this.between reference to?

@innovaat : this.between is a function in the component.

This is just an example
something like this
isBetween(value: any, filter: any[]) { //TODO check if value is null or filter is empty or filter.length == 2 if( filter[0] >= value && filter[1] <= value) { return true; } return false; }

@ramyapkumar : I try your soluce

But @ViewChild('dt') dataTable: DataTable;

what is DataTable, my file .ts dont' find this name. You can explain to me plz ?

Hey guys. No problem at all to apply your custom filter. Follow this code it makes your life happier =)
`
// in your template...

// in your ts
@ViewChild('tableSearch') tableSearch;

// this is your method that will do a dirty job for you =)
private applySearch(value: string, field: string, method = 'contains'): void {
this.tableSearch.filter(value, field, method);
}
`
hope it helps somebody, hope you enjoy. Have a nice coding time =)

I mixed @ramyapkumar @Maks-Yaremenko tips (implements AfterViewChecked,@ViewChild('tableSearch') tableSearch; etc) to make a good solution to filter "between dates" just a few tips to other people so new as me in Angular && PrimeNg who probably needs to do the same :

  • isBetween(value: any, filter: Date[])(at least with my angular version 7.2 you can do this)
  • value comes always like date-string so:
    const newDate = new Date(value);
  • Then you can compare dates using numbers like:
    if (newDate.valueOf() >= filter[0].valueOf() && newDate.valueOf() <= filter[1].valueOf())

Thanks a lot

Was this page helpful?
0 / 5 - 0 ratings