1

I am looking for specific regex matches in a text in a contenteditable div. I do find the correct matches:

<script>
const regex = /my_regex/g;
let content = $("#contenteditable").text();
let matches = content.match(regex);            

if (matches) {
    matches.forEach((match, groupIndex) => {
    // it finds the correct matches.    
    });
}
</script>

I want to highlight the matches in the text by wrapping each match in a <span> element with some styling

At first I tried using content.replace(//..) and then document.getElementById('contenteditable').textContent = content; or other methods using innerHTML but realized that it just reloads everything and not allowing the user to keep typing in the contenteditable div.

So I think the only way to do it is actually get the position of each match and replace each occurrence alone

So I found this post: Get a range's start and end offset's relative to its parent container

But then even if I have the caret position for each match, how can I replace only that? Is there any less complicated way to replace matches "on the fly" (as the user keeps typing without interrupting him), or it has to be done in these complicated ways?

pileup
  • 1
  • 2
  • 18
  • 45
  • There's no "_less complicated way_" to achieve what you need. The task is even more complicated than you might think. At first you've to [convert the mathces](https://developer.mozilla.org/en-US/docs/Web/API/Text/splitText) to [textnodes](https://developer.mozilla.org/en-US/docs/Web/API/Text), then you can [replace](https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild) the textnodes with [elements](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement). This way the entire element is not rewritten. – Teemu Feb 11 '22 at 10:23
  • [This answer](https://stackoverflow.com/a/70722437/1169519) might help you to get started. It doesn't do exactly what you need, but contains a useful function to find matches and an example of how to manipulate the content without rewriting everything. I haven't tested the code with contenteditables, though. – Teemu Feb 11 '22 at 10:29
  • thank you. will look at it – pileup Feb 11 '22 at 10:32
  • @Teemu I tried to use the above links to first simply manually replace a text in a `contenteditable` but couldn't get it to work. Could you please help me with the working fiddle just for the part of actually replacing text of the div given its position? – pileup Feb 11 '22 at 11:15
  • Utility function `searchTextNodes` seems to work also with contenteditable elements. Pass your contenteditable to `search`, and strip all the code related to the "UI" and also the `reset` code. Then specify your own regExp and pass it to `searchTextNodes`, change `mark` in the loop to `span`, and that's pretty much it. If you'll still face issues, maybe you should ask a new question, introduce the code you're using (the one you've applied from my code), and explain the issues with it in details. That way we'll have a decent SO question, which migh resolve issues future visitors are facing too. – Teemu Feb 11 '22 at 13:02
  • thank you, will try – pileup Feb 11 '22 at 19:25

0 Answers0