Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RegExp case insensitive multi word highlight

I am trying to get highlighting on keyword searching working right. A couple issues I am having.

  1. Case insensitive is working for the first word, but would like it to replace with original case word, not the lowercase searched word.

i.e. search trend, it replaces Trend with trend, I know why, but would like to figure out how to replace back the found word, not the searched word

  1. The second word is not matching case insensitive.

i.e. search trend micro is not matching trend Micro.

Here is jsFiddle: http://jsfiddle.net/hh2zvjft/1/

if ($(".ProjectSearch").val().length > 0) {
    var searchedText = $(".ProjectSearch").val();
    var wordList = searchedText.split(" ");
    $.each(wordList, function (i, word) {
        $(".ProjectTaskGrid:contains('" + word + "')").each(function (i, element) {
            var rgxp = new RegExp(word, "gi");
            var repl = '<span class="search-found">' + word + '</span>';
            element.innerHTML = element.innerHTML.replace(rgxp, repl);
        });
    });
}

Can you please help identify the issues, and offer improvements? Thanks!

Some refererences used to arrive at code:

https://stackoverflow.com/a/120161/2727155

https://stackoverflow.com/a/10011639/2727155

like image 495
AdamRoof Avatar asked Mar 15 '23 13:03

AdamRoof


1 Answers

Highlight multiple words (ignore HTML tags)

const regEscape = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const EL_input = document.querySelector("#input");
const EL_area = document.querySelector("#area");
const org = EL_area.innerHTML; // Store the current HTML state

const highlight = () => {
  const val = EL_input.value;
  
  if (!val) return EL_area.innerHTML = org;
    
  const pts = regEscape(val.trim()).split(/ +/);
  const reg = new RegExp("(?![^<]+>)(" + pts.join("|") + ")", "ig");
  const res = org.replace(reg, '<span class="highlight">$1</span>');
  
  EL_area.innerHTML = res;
};

EL_input.addEventListener("input", highlight);
highlight();
div {
  padding: 5px;
  border: solid 1px #CCC;
}

.highlight {
  background: gold;
}
<input id="input" autocomplete=off type="text" value="tren pan com br" />

<div id="area">
  Renew Trend Worry-Free Business Security license
  that <a href="http://someweb.com">someweb.com</a> will expire in 60 days.<br>
  Activate BR like breakline trend
  and [ confirm <span>SOME <span>SPAN</span> IS HERE</span>
  upon electronic<br> delivery notification
  from Trend Micro
</div>
like image 106
Roko C. Buljan Avatar answered Mar 30 '23 13:03

Roko C. Buljan