Jeff
Jeff

Reputation: 4433

Highlight multiple substrings in string -- javascript / jquery

tldr: How do I highlight multiple substrings in a javascript string variable (possibly with different colors that are readable with black text)? Simulated Desired Output:

sample_highlight

Long version

I have a span with some text:

<span>This is some text, there are lots of things in here. </span>

I also have a hash containing substrings to highlight:

h = {"t0": [0,2], "t1" : [8,15]}

I would like to highlight the text given the hash of arrays of substring starts and ends. It would look something like this:

This is some text, there are lots of things in here.

I thought about using html tags, but I can't figure out how to replace all the substrings at the same time:

Cumulative Try

First iteration

<tag1>Thi</tag1>s is some text, there are lots of things in here.

Second iteration

<tag1>Th<tag2>i</tag1</tag2>>s is some text, there are lots of things in here.
        ^ this is where the new 8th index is

Sequential Try

If I do it using the original value, I don't know how to add the results together:

First iteration

<tag1>Thi</tag1>s is some text, there are lots of things in here.

Second iteration

This is <tag2>some tex</tag2>t, there are lots of things in here.

Great! but how do I add those together?

Edit:

The tags could very well be nested:

<tag1>hello <tag2>world</tag2></tag1>

Not my normal use case, but I guess it could happen. Even if it just highlighted with a tooltip, that would be helpful, I guess?

Upvotes: 3

Views: 1850

Answers (1)

Zach
Zach

Reputation: 1964

Check out this function I put together. See it working in this JSFiddle

HTML

<span class="texttohighlight">This is some text, there are lots of things in here.</span>

JQuery/Javascript

var hash = {"t0": [0,2], "tabtest" : [4,8], "t1" : [9,25]};

highlightWords(hash);

function highlightWords(hash) {
    var offset = 0;
    var original;

    $.each(hash, function(key, val) {
        original = $(".texttohighlight").html();
        var length = original.length;
        var before = original.substring(0,val[0]+offset);
        var replace = original.substring(val[0]+offset, val[1]+offset);
        var after = original.substring(val[1]+offset,length);
        var final = before + "<span class='"+key+"'>" + replace + "</span>" + after;
        offset += 22 + key.length;
        $(".texttohighlight").html(final);
    });
}

CSS

.t0 {
   background:#00ff00;
}

.t1 {
    background:#00ffff;
}

.tabtest {
    background:#ccc;
}

It uses JQuery and creates span elements based on the numbers in the hash. The spans get the class of whatever the key is.

"t0": [0,2] will create

<span id="t0">Th</span>

Some Notes:

  • There cannot be overlap. The html tags won't work when overlapped and the colors wouldn't work anyway

  • Nested tags wont work, you could probably add some conditional logic and update the hash table based on whether or not the additional code was added before or after but you did mention its not your normal use case to have nested elements so I just added it into the loop for simplicity

  • You have to list the substrings in the order that they appear.

example:

  • {"t0": [0,2], "tabtest" : [4,8], "t1" : [9,25]}; works

  • {"tabtest" : [4,8], "t0": [0,2], "t1" : [9,25]}; will not work

This is because we add an offset to the substring numbers to compensate for the additional characters.

Upvotes: 1

Related Questions