I am trying to create a match strings highlighting matches in the following code. But, somehow, the results or output does not appear in the format I am setting in the div results (UL/LIs). Actually, I'would appreciate your advice to tackle this issue.
element.innerHTML = highlightedText; //if I comment this line, then the text works but, without format
function wrapMatchesInSpan(element, searchTerm) {
var text = element.textContent;
var regex = new RegExp(searchTerm, 'gi');
var matches = text.match(regex);
if (matches && matches.length > 0) {
var highlightedText = text.replace(regex, function(match) {
return '<span class="highlight">' + match + '</span>';
});
element.innerHTML = highlightedText; //if I comment this line, then the text works but, without format
}
}
function search() {
var searchTerm = document.getElementById("searchInput").value.toLowerCase();
var listItems = document.getElementById("searchResults").getElementsByTagName("li");
var teamItems = document.getElementById("searchTeams").getElementsByTagName("li");
var resultsDiv = document.getElementById("results");
for (var i = 0; i < listItems.length; i++) {
var listItem = listItems[i];
var text = listItem.textContent.toLowerCase();
if (text.includes(searchTerm)) {
listItem.innerHTML = listItem.innerHTML.replace(new RegExp(searchTerm, 'gi'), function(match) {
return '<span class="highlight">' + match + '</span>';
});
listItem.style.display = "list-item";
} else {
listItem.innerHTML = ''; // Clear the content
listItem.style.display = "none";
}
}
var hideAllTeams = true;
for (var j = 0; j < teamItems.length; j++) {
var teamItem = teamItems[j];
var teamText = teamItem.textContent.toLowerCase();
if (teamText.includes(searchTerm)) {
teamItem.style.display = "list-item";
hideAllTeams = false;
} else {
teamItem.style.display = "none";
}
}
if (searchTerm === "") {
resultsDiv.style.display = "none";
} else {
resultsDiv.style.display = "block";
}
if (hideAllTeams) {
teamsDiv.style.display = "none";
} else {
teamsDiv.style.display = "block";
}
}
* {
box-sizing: border-box;
}
#results {
display: none;
margin-top: 10px;
}
#searchResults {
background-color: #f6f6f6;
margin-top: -2px;
width: 430px;
height: 200px;
border: 1px solid #ddd;
}
#searchInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 425px;
font-size: 14px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#searchTeams {
list-style-type: none;
width: 425px;
font-size: 16px;
border: 1px solid #ddd;
}
#searchTeams li a {
color: 1px solid #ddd;
margin-top: -2px;
/* Prevent double borders */
background-color: #f6f6f6;
background-position: 10px 12px;
font-weight: bold;
padding: 12px;
text-decoration: none;
font-size: 19px;
color: black;
display: block
}
#teams {
color: 1px solid #ddd;
margin-top: -2px;
/* Prevent double borders */
padding: 12px;
text-decoration: none;
}
#searchTeams li a:hover:not(.header) {
background-color: #aeadca;
width: 100%;
padding-left: 35px;
color: blue;
}
ul.scroll {
background-color: #f6f6f6;
width: 600px;
height: 500px;
overflow-x: hidden;
overflow-y: auto;
text-align: left;
padding: 20px;
}
.highlight {
background-color: yellow;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NACC-Teams-Locator</title>
</head>
<body>
<div id="teams">
<h2>ACC Teams:</h2>
<input type="text" id="searchInput" placeholder="Search for teams / keywords / services..." oninput="search()">
<ul class="scroll" id="searchTeams">
<li style="display: list-item;"><a href="#">WMAA</a></li>
<li style="display: list-item;"><a href="#">MobileInf</a></li>
<li style="display: list-item;"><a href="#">MSM</a></li>
<li style="display: list-item;"><a href="#">SECAPPS</a></li>
<li style="display: list-item;"><a href="#">SECAPPS</a></li>
</ul>
<div id="results">
<h3>Services supported by team:</h3>
<ul id="searchResults" class="scroll">
<li style="display: none;">
<h3>MobileInf:</h3><br> -APIs<br> -Layer 7<br> -Gloo<br> -Gateways<br> -API portal</li>
<li style="display: none;">
<h3>Midrange Servers Management (MSM):</h3> -Servers<br> -Filesystem usage<br> -Patching<br> -Root<br> -API portal</li>
<li style="display: none;">
<h3>SECAPPS:</h3> -Okta<br> -Passwordsafe<br> -OIG<br> -Forgerock<br> -Evidian <br> -Cyberark<br> -go/password</li>
<li style="display: none;">
<h3>Hadoop:</h3> -Hive<br> -Cloudera<br> -Hue/Ambari<br> -Yarn/HDFS<br> -Hadoop Data Movement</b>
</li>
</ul>
</div>
</div>
<p>
//<img src="" />
</p>
</body>
</html>
As already mentioned in the comments, the innerHTML
gets changed every time when search()
is invoked. From the second call on, the search characters cannot be found because there exists <span></span>
tags. However, you can circumvent this problem by deleting the corresponding parts from innerHTML
each time when search()
is called.
for (var i = 0; i < listItems.length; i++) {
var listItem = listItems[i];
var text = listItem.textContent.toLowerCase();
listItem.innerHTML = listItem.innerHTML.replaceAll('<span class="highlight">', '')
listItem.innerHTML = listItem.innerHTML.replaceAll('</span>', '')
...