Press "Enter" to skip to content

Creating react-highlighter component

vpandzic 1

If you were creating your own autocomplete in jQuery, React or any other library/framework you probably wanted to highlight some letters of each item that matches user search criteria something like this:

react-highlighter-component

In this article I will explain idea, and also solution that has only few lines of code. When I tried to do this few years ago it took me more than 150 lines of code. Here I will explain how to create it using React and TypeScript.

If you want to do this only by CSS, well, it is not possible. Idea is to take text of some item and split it into multiple HTML tags and apply CSS class only to certain HTML elements.

If original item was

 

<span>Makarska - center</span>

and user types in kar newly created html would look like this:

<div class="d-inline">
<span class="">Ma</span>
<span class="bold">kar</span>
<span class="">ska - center</span></div>

If you know how JavaScript split function works you know that will not help in creating most elegant solution if you send to it just string delimiter. Problem is that when you try to split some string by another string it will not keep the separator.

Check this example:

var str = "How are you doing today?";
var res = str.split("o");

The result of res will be an array with the values:

H,w are y,u d,ing t,day?

This is definition of Split function
str.split([separator[, limit]])

Parameters

separator Optional

Specifies the string which denotes the points at which each split should occur. The separator is treated as a string or as a regular expression. If a plain-text separator contains more than one character, that entire string must be found to represent a split point. If separator is omitted or does not occur in str, the array returned contains one element consisting of the entire string. If separator is an empty string, str is converted to an array of characters.

So javascipt split function can receive regular expression with specified search term. This is what I inially tried:

 

var splitPattern = this.props.searchTerm != null ? new RegExp( this.props.searchTerm , "i") : '';
var miniWords = name.split(splitPattern);

 

There were few problems. First I didn’t put search term in capturing group so I get same effect if I do:

var miniWords = name.split(this.props.searchTerm);

Other problem is that I needed a way to ignore casing. Luckily RegExp as second parameter accepts flag “i” that basicly means ignore casing.

Combining those two this is I came up with:

 

var splitPattern = this.props.searchTerm != null ? new RegExp("(" + this.props.searchTerm , "i") : '';
var miniWords = name.split(splitPattern);

This is whole render function of the component:

import * as React from 'react'

export default class HighLighter extends React.Component<IHighLighterProps, IHighLighterState>{

constructor(props: IHighLighterProps) {
super(props);
}
renderName(name: string) {

var splitPattern = this.props.searchTerm != null ? new RegExp("(" + this.props.searchTerm , "i") : '';
var miniWords = name.split(splitPattern);

var html = [];

_.each(miniWords, (miniWord, index) => {
if (this.props.searchTerm != null && miniWord.toLowerCase() == this.props.searchTerm.toLowerCase()) {
html.push(<span className={this.props.highlightedItemClass}>{miniWord}</span>)
} else {
html.push(<span className={this.props.itemClass}>{miniWord}</span>)
}

});

return <span> {html}</span>;
}
render() {
const { wrapperClass } = this.props;
return (
<div className={wrapperClass}>{this.renderName(this.props.text)}</div>
)
}
}
interface IHighLighterProps {
searchTerm: string;
text: string;
wrapperClass: string;
highlightedItemClass: string;
itemClass: string;
}
interface IHighLighterState {
}

 

 

  1. Amazing! Its really remarkable article, I have got much clear idea
    about from this post.

Leave a Reply

Your email address will not be published. Required fields are marked *