Global Search
All Columns Search
The behavior of client side search functionality can be customized by overriding
. In below example, the search is applied to all columns based on the text displayed on the table. You can search on string, number, date, and datetime columns as displayed on the table.
That example uses custom pagination component explained in
Below is the code of the datasource.
global-search-datasource.ts
import { CellFormatter , ColumnDefinition , PanemuTableDataSource , TableCriteria } from "ngx-panemu-table";
export class GlobalSearchDataSource<T> extends PanemuTableDataSource <T> {
private formatters: { [key: string]: CellFormatter } = {};
constructor(columns: ColumnDefinition <T>) {
super()
this.formatters = columns.body.map(col => ({ [col.field]: col.formatter! })).reduce((acc, cur) => ({ ...acc, ...cur }), {});
}
protected override filter(result: T[], tableCriteria: TableCriteria []): T[] {
if (!tableCriteria?.length || !tableCriteria[0].value) {
return result;
}
let searchKeyword = String(tableCriteria[0].value).toLowerCase();
return result.filter((item: any) => {
for (const field of Object.keys(this.formatters)) {
let formattedValue = String((this.formatters[field](item[field]) ?? '')).toLowerCase();
if (formattedValue.includes(searchKeyword)) {
return true;
}
}
return false;
})
}
}
That example also uses custom
to hight light texts matching search term.
highlight-cell-renderer.ts
highlight-cell-renderer.html
highlight.pipe.ts
import { CommonModule } from '@angular/common';
import { Component, Input, OnInit, signal, Signal, TemplateRef } from '@angular/core';
import { CellComponent , CellFormatterPipe , CellRenderer , PropertyColumn } from 'ngx-panemu-table';
import { HighlightPipe } from './highlight.pipe';
@Component({
standalone: true,
imports: [CommonModule, HighlightPipe],
templateUrl: 'highlight-cell-renderer.html',
})
export class HighlightCellRenderer implements CellComponent <any>, OnInit {
row!: any;
column!: PropertyColumn <any>
parameter?: any;
searchTerm!: Signal<string>;
ngOnInit(): void {
this.searchTerm = this.parameter?.searchTerm ?? signal('');
}
static create(searchTerm: Signal<string>): CellRenderer {
return {
component: HighlightCellRenderer,
parameter: {searchTerm}
}
}
}
Per Column Search
Below is an example of how to implement per-column search with search field in every column header.
column-search-datasource.ts
import { CellFormatter , ColumnDefinition , PanemuTableDataSource , TableCriteria } from "ngx-panemu-table";
export class ColumnSearchDataSource<T> extends PanemuTableDataSource <T> {
private formatters: { [key: string]: CellFormatter } = {};
constructor(columns: ColumnDefinition <T>) {
super()
this.formatters = columns.body.map(col => ({ [col.field]: col.formatter! })).reduce((acc, cur) => ({ ...acc, ...cur }), {});
}
protected override filter(result: T[], tableCriteria: TableCriteria []): T[] {
if (!tableCriteria?.length || !tableCriteria[0].value) {
return result;
}
return result.filter((item: any) => {
for (const crit of tableCriteria) {
let searchKeyword = String(crit.value).toLowerCase();
let formattedValue = String((this.formatters[crit.field](item[crit.field]) ?? '')).toLowerCase();
if (!formattedValue.includes(searchKeyword)) {
return false;
}
}
return true;
})
}
}
header-filter.component.ts
header-filter.component.html
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { HeaderComponent , HeaderRenderer , PanemuTableController , PropertyColumn } from 'ngx-panemu-table';
import { debounceTime, distinctUntilChanged } from 'rxjs';
@Component({
templateUrl: 'header-filter.component.html',
imports: [CommonModule, ReactiveFormsModule],
standalone: true
})
export class HeaderFilterComponent implements OnInit, HeaderComponent {
column!: PropertyColumn <any>;
parameter?: any;
controller!: PanemuTableController <any>;
txtFilter = new FormControl();
ngOnInit() {
this.controller = this.parameter.controller;
this.txtFilter.valueChanges.pipe(
debounceTime(250),
distinctUntilChanged()
).subscribe(val => {
let crit = this.controller.criteria.find(item => item.field === this.column.field);
if (val) {
if (!crit) {
crit = {field: String(this.column.field), value: val}
this.controller.criteria.push(crit)
} else {
crit.value = val
}
} else {
if (crit) {
this.controller.criteria = this.controller.criteria.filter(item => item.field != this.column.field)
}
}
this.controller.reloadData();
})
}
static create(controller: PanemuTableController <any>): HeaderRenderer {
return {component: HeaderFilterComponent, parameter: {controller}}
}
}