Creating a Highlighter in Vanilla JS
I think thrice in recent past I needed a highlighter while coding. Two times, I used the plugin. Once the jQuery plugin, and the second time, a react plugin. Then when I was creating a filter (by the way, filters are my favourite), I needed the highlighter once more. I opened a new tab in the browser and hit the keywords. I had used a react highlighter a few months ago, so I knew what exactly I needed. I copied the code to install the package from their GitHub page, and just when I was about to hit enter after pasting the clipboard content on the command line, something else hit me.
Why use a plugin?
I asked myself, why do I need to use a plugin for this simple task. Isn’t highlighting is all about splitting the string and then surrounding the matched substring with some styles in a span tag?
I wrote a function within a few minutes, but when I ran it and tested in my actual development, it failed. I checked the algorithm once again and I could see what I was doing wrong.
So one of the key steps of creating a highlighter of this kind is, we need to ignore character cases. Then how do we find the character case-insensitive substring? The regular expression was the answer.
How it works.
Find the case-insensitive match in the given string.
Divide the string using case-insensitive split.
Join the split and matched parts by adding required styles in the matched parts.
Here is the code in Vanilla JS.
/**
* @description function to convert a simple string into
* an HTML element with parts of it highlighted.
* @params {String} str given string
* @params {String} query substring which needs to be
* highlighted.
* @returns {HTML Element}
*/
function getHighlightedString (str, query) {
try {
var len = str.length;
if (len) {
/**
* 1. create the case-insensitive and global regex.
* 2. Find the matches.
* 3. Split the given string.
* 4. Initialise an empty array.
*/
let reg = new RegExp (query, "ig"),
matches = str.match (reg),
parts = str.split (reg),
tempStr = [];
// do the following only if we have parts of string available, and we have found matches.
if (parts.length && matches && matches.length) {
/**
* 1. Push the part of the string into the new array.
* 2. Create a temp string with required style using the first match.
* 3. Push the temp string into the new array (i.e. after first part).
* 4. Repeat till we reach the last part of the string.
* IMP: Match substrings count will always be one less than the split parts.
*/
for (let count = 0; count < parts.length; count++) {
tempStr.push (parts[count])
if (matches[count]) {
var temp = "<b class='highlight-class'>" +
matches[count] +
"</b>";
tempStr.push (temp);
}
}
// after all parts have been collected, join the array and return
str = tempStr.join ("");
}
} else {
throw "Empty String";
}
return str;
} catch (e) {
console.trace ("Error ", e);
}
}
Leave a Reply