Highlighting Text Within a String Using Vue.js and Regular Expressions

Highlighting Text Within a String Using Vue.js and Regular Expressions image

Something that always seems to come up in my development is the need to find character combinations within a string and render those characters in a special way to the end user. Earlier in 2017, I wrote an article titled, Highlight Text Within a String Using Angular and Regular Expressions, which focused on highlighting text in a string using the very popular Angular framework. Using regular expressions, the text was replaced with an HTML-wrapped equivalent to give it a nice highlighting effect.

Angular isn't the only web framework on the internet. There are other popular frameworks that work in a similar fashion but are still very different.

We're going to see how to highlight text within a string using the very popular Vue.js JavaScript framework.

Creating a Vue.js Project for Text Manipulation

To keep things simple and easy to understand, we're going to create a fresh Vue.js project. The goals are as follows:

  1. Display a paragraph stored as a variable within the HTML.
  2. Accept user input to be used for querying.
  3. Use regular expressions to perform a find-and-replace based on the user input and the stored paragraph.
  4. Display the new paragraph, which includes replaced content.

Assuming you've already installed the Vue CLI, execute the following from a Command Prompt (Windows) or Terminal (Mac and Linux):

vue init webpack regex-project

When prompted, answer any questions that come up. We won't be using a router, and it doesn't matter if you choose compiler with runtime project or runtime project only.

The Vue CLI will scaffold a lot of things for us, but we'll be spending all our time in the App.vue file. Open this file and include the following:

<template>
    <div id="app">
        <img src="./assets/logo.png">
    </div>
</template>

<script> export default { name: 'app', data() { return { query: "", content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim leo massa, sed aliquet leo posuere ut. Curabitur malesuada accumsan erat, id varius eros tincidunt quis. Vivamus lobortis, odio at fermentum efficitur, risus est tincidunt nisl, eget condimentum tellus dui vitae nibh. Donec id lorem condimentum, porttitor augue in, fermentum leo. Morbi condimentum, nunc ut malesuada placerat, sem nulla condimentum purus, iaculis tristique metus diam lobortis enim. Suspendisse potenti. Quisque urna magna, porta eget erat ac, pharetra vehicula erat. Suspendisse sed nisi ex." } }, methods: { } </script>

<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .highlightText { background: yellow; } </style>

In the above code, you'll notice that we have the typical <template>, <script>, and <style> blocks that you'd expect in a Vue.js application.

In the data method, you'll see that we are initializing two variables. The query variable will represent our user input and be bound to form input, and the content variable represents some lorem ipsum to be searched and highlighted.

Let's take a closer look at the methods in the <script> block:

methods: {
    highlight() {
        if(!this.query) {
            return this.content;
        }
        return this.content.replace(new RegExp(this.query, "gi"), match => {
            return '<span class="highlightText">' + match + '</span>';
        });
    }
}

For this example, we have a single function called highlight. When called, the query variable will be checked to see if it is empty. If it is empty, the original content variable will be returned. If it is not empty, we do a string replace. We search the content for the query and return the match wrapped in some HTML with a class that looks like this:

.highlightText {
    background: yellow;
}

So how do we make use of this in the HTML that is actually rendered to the screen? Let's take another look at the <template> block, but this time with some modifications:

<template>
    <div id="app">
        <img src="./assets/logo.png">
        <div>
            Search: <input type="text" v-model="query" placeholder="Search" />
        </div>
        <br />
        <div v-html="highlight()"></div>
    </div>
</template>

This time around, we have an <input> tag bound to the query variable with the v-model attribute. In theory, we could just print out the result of our highlight method by saying , however, HTML won't be rendered in this scenario. Instead, we have to use:

<div v-html="highlight()"></div>

The v-html in the above line will render any HTML that appears in our string. This means that any matches to our regular expression will be highlighted yellow.

The full code to this project would look like this:

<template>
    <div id="app">
        <img src="./assets/logo.png">
        <div>
            Search: <input type="text" v-model="query" placeholder="Search" />
        </div>
        <br />
        <div v-html="highlight()"></div>
    </div>
</template>

<script> import HelloWorld from './components/HelloWorld' export default { name: 'app', data() { return { query: "", content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse dignissim leo massa, sed aliquet leo posuere ut. Curabitur malesuada accumsan erat, id varius eros tincidunt quis. Vivamus lobortis, odio at fermentum efficitur, risus est tincidunt nisl, eget condimentum tellus dui vitae nibh. Donec id lorem condimentum, porttitor augue in, fermentum leo. Morbi condimentum, nunc ut malesuada placerat, sem nulla condimentum purus, iaculis tristique metus diam lobortis enim. Suspendisse potenti. Quisque urna magna, porta eget erat ac, pharetra vehicula erat. Suspendisse sed nisi ex." } }, methods: { highlight() { if(!this.query) { return this.content; } return this.content.replace(new RegExp(this.query, "gi"), match => { return '<span class="highlightText">' + match + '</span>'; }); } } } </script>

<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .highlightText { background: yellow; } </style>

To see the project in action, it can be run with the Node Package Manager (NPM) like so:

npm run dev

Then, when you navigate to http://localhost:8080 in your web browser, you can do a live search within the paragraph.

Conclusion

You just saw how to make use of regular expressions within a Vue.js web application to highlight text in a string and render it on the page. This is very similar to an Angular variation that I had written about previously.

Knowing how and when to use regular expressions is a great skill to have, even in JavaScript development.

KEEP MOVING FORWARD

Nic Raboy / javascript