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.
1 | Abagail Kingscote | Female | Philippines | 9,339.72 | Wed, 26 Apr 2023 | 3 Jul 2024 9:56:29 | Yes | |
2 | Nicolina Coit | Male | Kazakhstan | 3,744.95 | Wed, 1 Nov 2023 | 29 Apr 2024 12:48:59 | No | |
3 | Sarene Greim | Male | United States | 4,397.68 | Tue, 3 Jan 2023 | 3 Jun 2024 13:14:23 | Yes | |
4 | Blair Millbank | Female | Philippines | 3,334.58 | Sat, 1 Jul 2023 | 18 Jun 2024 12:06:58 | No | |
5 | Kliment Sprowle | Male | Indonesia | 6,459.93 | Mon, 25 Dec 2023 | 24 Apr 2024 3:46:26 | Yes | |
6 | Winifred Dikle | Female | Kazakhstan | 9,833.93 | Sun, 6 Aug 2023 | 19 May 2024 14:39:17 | No | |
7 | Chadd Nacci | Male | China | 4,383.54 | Tue, 3 Jan 2023 | 12 May 2024 11:25:03 | Yes | |
8 | Matthiew Morland | Female | Greece | 9,727.90 | Sun, 22 Oct 2023 | 25 Mar 2024 10:35:03 | No | |
9 | Perceval Glasheen | Male | Netherlands | 7,201.29 | Sun, 23 Jul 2023 | 1 Jul 2024 17:23:03 | Yes | |
10 | Fenelia Oblein | Male | Sweden | 3,654.03 | Fri, 13 Oct 2023 | 25 Jul 2024 10:20:02 | No |
Page 1 of 27 ( 266 rows )
Go to page
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 uses custom cell renderer to hight light text 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('');
}
/**
* Create a custom cell renderer using `ng-template`.
* @param templateRef
* @returns
*/
static create(parameter?: Record<string, any>): CellRenderer {
return {
component: HighlightCellRenderer,
parameter
}
}
}
Per Column Search
Below is an example of how to implement per-column search with search field in every column header.
Id | Name | Email | Gender | Country | Amount | Enrolled | Last Login | Verified |
---|---|---|---|---|---|---|---|---|
Rows: 266 |
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}}
}
}