Highlighting text based on user input

I have the following code which highlights text (changes text color to RED) within my repeater for all the items returned from the database based on the user’s input value from an input element (#searchText).

        
 $w("#repeater1").forEachItem( ($item, itemData, index) => {
            var src_str = $item("#text85").html;
            var term = $w("#searchText").value;
            term = term.replace(/(\s+)/,"(<[^>]+>)*$1(<[^>]+>)*");
            var pattern = new RegExp("("+term+")", "i");
           src_str = src_str.replace(pattern, "<span style='color:red'>$1</span>");
           src_str = src_str.replace(/(<span style='color:red'>[^<>]*)((<[^>]+>)+)([^<>]*<\/span>)/,"$1</span>$2<span                      style='color:red'>$4");
           $item("#text85").html = (src_str);
} );

Code works great the first time the user selects a term in the input box.
The second time the user searches a term, it highlights their selection again in the repeaters, but it also keeps the red highlights from the first search.

I am trying to figure out how to remove the span from the first time a users searches, so it only highlights the new search term items on subsequent searches. See screen shots below.

Any help is greatly appreciated!

First search:

Second search:

I’ve figured it out. I now clear any existing highlighted span tags first and then apply the new highlighted span tag to the new search value.

Here is the updated code.

$w( “#repeater1” ).forEachItem( ($item, itemData, index) => {
var src_str;
src_str = $item( “#text85” ).html;
src_str = src_str.replace( ‘’,‘’ );
var term = $w( “#searchText” ).value;
term = term.replace(/(\s+)/, “(<[^>]+>)$1(<[^>]+>)” );
var pattern = new RegExp( “(” +term+ “)” , “i” );
src_str = src_str.replace(pattern, ‘$1’ );
var old_str = src_str;
$item( “#text85” ).html = (src_str);
} );

Next issue…running into an issue where if the user enters a term which is in one of the HTML tags of the text85 element, it breaks the page display.
See screen shot. So the highlighting is working, but if any search term is part of an HTML tag, it really messes things up.
I’ve tried pulling only the .text and appending the HTML code, but it is just not working yet.

My temporary work-around is to evaluate the user’s search term and if it equals a few of the HTML tags which break the code, I display an error message. I also display the message if the search term is less than 4 characters long.

Not perfect, but should eliminate 99% of chances to break the page for now.

@scottb You can try:

const value = $w("#searchText").value;
const p = src_str.split(">").filter(e => e).map(e => ({particle: e}));
let t = p.filter(e => !e.particle.trim().startsWith("<")).map(e => {e.particle = e.particle.split("<"); return e;}).map(e => {e.particle[0] = e.particle[0].replace(value, `<span style="color:red;">${value}</span>`); return e;});
t.forEach(e => e.particle = e.particle.join("<"));
$item("#text85").html = p.reduce((a,c) => a + c.particle + ">", "");

@jonatandor35 Excellent…just 1 little thing. Getting an additional closing ‘>’ at the end of the string.
Thank you so much.

@scottb I’ve updated the code above.

@jonatandor35
It was still showing up…but I updated this line to slice the last character…

$item("#text85").html = p.reduce((a,c) => a + c.particle + ">", "").slice(0,-1);

Is there a way to make this all case insensitive?

@scottb
I think that if you put:
. filter ( e => e )
in the second line (see update above) it will solve the extra “>” (but your way can also work). It’s the same.
If you wish to make a replace case-insensitive, you’ll have to use regex.
Google “case insensitive replace method” and you’ll find plenty of explanations how to do it…

@jonatandor35 Thanks again…I think I have it all working as designed now.