

Finally came up with a way to highlight matching text and display the result in its original case
Edit: This is a way to highlight text that matches a string identified dynamically in the app -- via a text input or in some other way. It's more targeted than using Ctrl+F in the browser UI.
I hope this is helpful to someone. I was really excited when this solution popped into my head.
A year or so ago, I had come up with what is shown in the second screenshot, where the gallery text is in all caps: Convert the whole text to uppercase, then replace instances of the filter text (uppercased) with span tags with yellow background containing the filter text (also uppercased). Not ideal, but it was the only way I knew of to get all matches for the specified text regardless of what case they have in the source.
Yesterday, I came up with the variation shown in the first screenshot, where the gallery text is in mixed case. This approach highlights the matches regardless of case and allows the displayed text to have its original case. There are trade-offs. Notably, the displayed text has to be in a monospace font, but IMO it's better than making it all uppercase (or all lowercase). It also doesn't work if the HTML text control is very wide (Edit: If it's too wide, the highlights might not align with the matched text). In my example, it's 700, and that works fine.
The trick is to use two HTML text controls, one layered exactly on top of the other.
- The first one, ParagraphHTML, is just the original text, without any highlighting substitutions.
- The second one, ParagraphHighlightsHTML, renders just the highlights -- no visible text. Its HtmlText property is ParagraphHTML.HtmlText, converted to lowercase, with highlighting substitutions, and with color: transparent applied to the whole thing. The monospace font is necessary to ensure that the all-caps and mixed-case versions of the text will have the matching text in the same places.
I can share a zip file of my demo app on request. Just message me with your email address. But here are the operative bits:
This is the HtmlText property of ParagraphHTML:
/*
Put a non-breaking space ( ​ ) before the div; otherwise, inline CSS may not be applied to the first item in the gallery.
Apply a monospace font family to the div -- I am using Conolas -- so the spacing and widths of characters will be the same in ParagraphHTML and ParagraphHighlightsHTML even though they have different capitalization.
*/
"&#8203;<div style='font-family: Consolas'>" & ThisItem.Value & "</div>"
And this is the HtmlText property of ParagraphHighlightsHTML:
/*
Working outward from the innermost piece:
Start with ParagraphHTML.HtmlText.
Lowercase it: Lower(ParagraphHTML.HtmlText)
Use the substitute function on that to replace
TextInput1.Text (lowercased)
with
TextInput1.Text (lowercased) wrapped in a span tag with a yellow background.
Wrap the whole thing in a span tag that makes the text transparent so only the background color of each substituted span is visible.
*/
"<span style='color: transparent;margin:0;padding:0'>"&Substitute(Lower(
ParagraphHTML
.HtmlText),Lower(
TextInput1
.Text),"<span style='background-color: #fff59d'>"&
TextInput1
.Text&"</span>")&"</span>"