Highlighting the Searched Text while Filtering in the Grid
Environment
Product | Progress® Kendo UI® Grid for Angular |
Description
How can I highlight the searched text entered in a TextBox while filtering all the columns in the Kendo UI for Angular Grid?
Solution
To highlight the searched text in the Grid, implement a custom directive that manipulates the DOM based on the currently entered value by using Angular's Renderer2
APIs. Use the CellTemplateDirective
of the Grid to apply the custom highlighting directive to an HTML element that will display the manipulated cell content.
<kendo-grid-column field="ProductName" title="Product Name">
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
<div searchHighlight [searchValue]="value" [text]="dataItem.ProductName"></div>
</ng-template>
</kendo-grid-column>
Custom Directive Implementation
Configure the custom directive to implement the onChanges
lifecycle hook. Use the ngOnChanges
method to track the value changes of the input and implement the highlighting logic in this method.
Also, configure two input properties for the custom directive. One that accepts the current value of the TextBox input and the other—bound to the content of the corresponding cell.
@Directive({
selector: '[searchHighlight]'
})
export class HighlighterDirective implements OnChanges {
@Input() text: string;
@Input() searchValue: string;
// ...
}
The next five steps explain how to implement the highlighting logic of the custom directive:
-
Clear the text content of the Grid cells at the beginning of each execution of the
ngOnChanges
method by getting a reference to the host element of the directive and removing the first child of this element. Then, if no searched value is entered, use theappendChild
andcreateText
methods to append the default cell content to the host element, and exit the current execution of the hook:tsconstructor(private renderer: Renderer2, private element: ElementRef) {} public container = this.element.nativeElement; public ngOnChanges(): void { // Clear content of Grid cells. while (this.container.firstChild) { this.container.removeChild(this.container.firstChild); } // Append default cell content and exit. if (!this.searchValue) { this.renderer.appendChild(this.container, this.renderer.createText(this.text)); return; } this.highlightSearchText(); }
-
When a value is entered in the search input, configure a regular expression with the searched value and a global, case-insensitive modifier ('gi') as arguments. Use this expression to split the text of the corresponding cell and separate the searched value from the rest of the cell text:
tspublic highlightSearchText(): void { // Split text based on the searchValue. const re = new RegExp(`(${this.searchValue})`, 'gi'); const strings = this.text.split(re); // ... }
-
Compare each part of the split text with the searched value. In case the corresponding part matches the searched value, append it to a newly created
span
element. Otherwise, append the text part to the host element without modifying it further.tspublic highlightSearchText(): void { // ... strings.forEach(string => { if (string !== "" && string.toLowerCase() === this.searchValue.toLowerCase()) { // Append the string to a highlighted span element. this.appendToSpan(string); } else { // Append the string without highlighting it. this.renderer.appendChild(this.container, this.renderer.createText(string)); } }); }
-
To create a new
span
element, use thecreateElement
method and add a specific class to it with the help of theaddClass
method. Then, append the matched text part to the createdspan
element, and in turn, append thespan
to the container host element.tspublic appendToSpan(string: string): void { const span = this.renderer.createElement('span'); this.renderer.addClass(span, 'highlight'); // Append matched string to span. this.renderer.appendChild(span, this.renderer.createText(string)); // Append span to host element. this.renderer.appendChild(this.container, span); }
-
Apply a desired highlighting background-color to the created
span
elements by using the previously defined class:css.highlight { background-color: yellow; }
The following example demonstrates the full implementation of the suggested approach.