I want to highlight the text that is searched in the datatable filter field, I am using material data table with angular. I create a pipe for highlight, and send the text search as an arg
export class HighlightSearchPipe implements PipeTransform {
private destroyed$: Subject<void> = new ReplaySubject(1);
constructor( private sanitizer: DomSanitizer) {}
transform(value: any, args?: any): any {
if (!value) {
return observableOf(value);
}
/** Data table filtering */
if (args) {
const searchText = args[0];
const re = new RegExp(searchText, 'gi');
const match = value.match(re);
// If there's no match, just return the original value.
if (!match) {
return value;
}
value = value.replace(re, '<mark class="saqr-first-mark">' + match[0] + '</mark>');
return observableOf(value);
}
and in the material datatable typescript file I add the highlight into the constructor
constructor(
private highlight: HighlightSearchPipe,
) {}
applyFilter() {
this.dataSource.filter = this.searchKeyword.trim().toLowerCase();
this.highlight.transform(this.dataSource.filter, this.searchKeyword);
// here cannot detect that
}
What do you suggest to do for data table highlighting the searched text?
I've managed to produce a working demo of this. My HighlightSearchPipe
class is as follows:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'highlightSearch'
})
export class HighlightSearchPipe implements PipeTransform {
transform(value: string, search: string): string {
const valueStr = value + ''; // Ensure numeric values are converted to strings
return valueStr.replace(new RegExp('(?![^&;]+;)(?!<[^<>]*)(' + search + ')(?![^<>]*>)(?![^&;]+;)', 'gi'), '<strong class="your-class">$1</strong>');
}
}
I've modified Typescript class that contains the applyFilter()
function as follows:
i. Added the filterText
class variable so the filter text typed by the user can be accessed in the HTML. This variable is updated in the applyFilter()
function
ii. Removed the call to this.highlight.transform(this.dataSource.filter, this.searchKeyword);
in applyFilter()
@Component({
...
})
export class TableFilteringExample {
...
filterText = '';
applyFilter(filterValue: string) {
this.filterText = filterValue.trim();
this.dataSource.filter = this.filterText.toLowerCase();
}
}
In the component HTML I've changed the way the cells are rendered from:
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element">{{element.name}}</td>
</ng-container>
to:
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element" [innerHTML]="element.name | highlightSearch: filterText"></td>
</ng-container>
This way the cell value (in this case element.name
) is capable of rendering HTML. It uses the highlightSearch
pipe in order to transform the value and highlight the portion of it that matches the filter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With