Home > Software design >  How to highlight text when entering into input search bar
How to highlight text when entering into input search bar

Time:12-12

function myFunction() {
    // Declare variables
    var input, filter, ul, li, a, i, txtValue;
    input = document.getElementById('myInput');
    filter = input.value.toUpperCase();
    ul = document.getElementById("myUL");
    li = ul.getElementsByTagName('li');
  
    // Loop through all list items, and hide those who don't match the search query
    for (i = 0; i < li.length; i  ) {
      a = li[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        li[i].style.display = "";
        li[i].style.color = 'green';
      } else {
        li[i].style.display = "none";
      }
    }
  }
 body{
    margin: 0;
  }
  .center{
    margin-left:auto;
    margin-right: auto;
    width: 1200px;
  }
  nav {
    height: 80px;
    background: #9bcfe0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    
  }
  
  .logo {
    color: white;
    border-radius: .5;
    font-size: 1.5rem;
    font-weight: bold;
    font-style: italic;
    padding: .5rem 2rem;
    margin-left: 10px;
    border-radius: 25px;
    background-color: #e76f3d;
  }
  
  nav a {
    text-decoration: none;
    color: #000;
    padding: 0 1.5rem;
    
  }
  
  nav a:hover {
    color: #fff;
    background-color: #e76f3d;
  }
  
  .nav-items{
    font-weight: bold;
    margin-right: 10px;

  }
 
  .Main-Items{
    display: flex;
    justify-content: space-around;
    margin-left:20%;
    margin-right:20%;
    padding-top: 10px;
    margin-bottom: 20px;
    font-size: 20px;
    
  }
  .Main-Items a{
    text-decoration: none;
    color: #1167b1;
    padding-right: 10px;
    margin-left:10px;
 }

  .Main-Items a:hover{
    color: white;
    background: #e76f3d;

  }
/***Search bar***/ 

  #myInput {
    background-image: url('/css/searchicon.png'); /* Add a search icon to input */
    background-position: 10px 12px; /* Position the search icon */
    background-repeat: no-repeat; /* Do not repeat the icon image */
    margin-left:10%;
    width: 74%;
    font-size: 16px; /* Increase font-size */
    padding: 12px 20px 12px 40px; /* Add some padding */
    border: 1px solid #ddd; /* Add a grey border */
    margin-bottom: 12px; /* Add some space below the input */
  }
  
  #myUL {
    /* Remove default list styling */
    list-style-type: none;
    padding: 0;
    margin: 0;
    margin-left: 10%;
    margin-right: 10%;
  }
  
  #myUL li a {
    /***
    border: 1px solid #ddd; /* Add a border to all links */
    margin-top: -1px; /* Prevent double borders */
    background-color: white; /* Grey background color */
    padding: 15px; /* Add some padding */
    text-decoration: none; /* Remove default text underline */
    font-size: 20px; /* Increase the font-size */
    color: #1167b1; /* Add a black text color */
    display: block; /* Make it into a block element to fill the whole list */
  }
  
  #myUL li a:hover:not(.header) {
    background-color: #eee; /* Add a hover effect to all links, except for headers */
  }
  /***
  @media screen and (max-width: 768px) {
    .hero-container {
      grid-template-columns: 1fr;
    }
  }
  ***/
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="Styles1.css">
</head>
<body>
  <script src="scripts.js"></script>
  <div >
  <nav>
    <div >Nexamp</div>
    <div >
      <a href="/">Home</a> <a href="/">About</a> <a href="/">Contact</a>
    </div>
  </nav>
  <div class = "Main-Items">
   <strong>Collections:</strong>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
  </div>
  <section >

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">

<ul id="myUL">
  <li><a href="#">Community Solar</a></li>
  <li><a href="#">Organic</a></li>

  <li><a href="#">Company Organization</a></li>
  <li><a href="#">Bob</a></li>

  <li><a href="#">Calvin</a></li>
  <li><a href="#">Christina</a></li>
  <li><a href="#">Cindy</a></li>
</ul>
  </section>
 </div>
</body>
</html>

Search Bar Without Entry Search Bar With Entry In the images above, I have a search bar that allows for input, and filters once an input has been given. However, I want to go one step further and add a highlight to the text when an input has been made. In this example, for picture 2, I would want text highlighted for those selected. This is my current code below.

This would be my desired output

CodePudding user response:

Actually, I did not analyze your whole codes. But I made a part what you want. I assume you can integrate these. Here:

function onInput(input) {
    highlight(input, document.querySelector('#target-text'))
}

function highlight(input, target) {
    const value = input.value
    const matches = findText(target.textContent, input.value)
    unwrap(target)
    matches.forEach(match => target.innerHTML = wrap(target.textContent, match[0], match[1]))
}

function findText(string, search) {
    const matches = []
    let i = -1
    let ind = 0
  
    do {
        i = string.indexOf(search, i   1)
        if (i > -1) matches.push([i, i   search.length])
    }
    while (i > -1 && search)
    
    return matches
}

function wrap(text, from, to) {
    if ((from !== 0 && from < 1) || !to) return text
    return `${text.slice(0, from)}<span >${text.slice(from, to)}</span>${text.slice(to, text.length)}`
}

function unwrap(wrapper) {
    return Array.from(wrapper.querySelectorAll('.highlight')).forEach(target => target.replaceWith(target.textContent))
}
.highlight {
  color: green;
}
<input id="search-input" oninput="onInput(this)"/>
<div id="target-text">search text</div>

CodePudding user response:

You can replace each link's text and create a span with the matched characters using String.prototype.slice.

function myFunction() {
    // Declare variables
    var input, filter, ul, li, a, i, txtValue;
    input = document.getElementById('myInput');
    filter = input.value.toUpperCase();
    ul = document.getElementById("myUL");
    li = ul.getElementsByTagName('li');
  
    // Loop through all list items, and hide those who don't match the search query
    for (i = 0; i < li.length; i  ) {
      a = li[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      let matchStart;
      if ((matchStart = txtValue.toUpperCase().indexOf(filter)) > -1) {
      
        // Replace link text to include highlighted span
        a.innerHTML = '';
        a.appendChild(document.createTextNode(txtValue.slice(0, matchStart)));
        const highlighted = document.createElement('span');
        highlighted.classList.add('highlighted');
        highlighted.innerText = txtValue.slice(matchStart, matchStart   filter.length);
        a.appendChild(highlighted);
        a.appendChild(document.createTextNode(txtValue.slice(matchStart   filter.length)));
        
        li[i].style.display = "";
        li[i].style.color = 'green';
      } else {
        li[i].style.display = "none";
      }
    }
  }
body{
    margin: 0;
  }
  .center{
    margin-left:auto;
    margin-right: auto;
    width: 1200px;
  }
  nav {
    height: 80px;
    background: #9bcfe0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    
  }
  
  .logo {
    color: white;
    border-radius: .5;
    font-size: 1.5rem;
    font-weight: bold;
    font-style: italic;
    padding: .5rem 2rem;
    margin-left: 10px;
    border-radius: 25px;
    background-color: #e76f3d;
  }
  
  nav a {
    text-decoration: none;
    color: #000;
    padding: 0 1.5rem;
    
  }
  
  nav a:hover {
    color: #fff;
    background-color: #e76f3d;
  }
  
  .nav-items{
    font-weight: bold;
    margin-right: 10px;

  }
 
  .Main-Items{
    display: flex;
    justify-content: space-around;
    margin-left:20%;
    margin-right:20%;
    padding-top: 10px;
    margin-bottom: 20px;
    font-size: 20px;
    
  }
  .Main-Items a{
    text-decoration: none;
    color: #1167b1;
    padding-right: 10px;
    margin-left:10px;
 }

  .Main-Items a:hover{
    color: white;
    background: #e76f3d;

  }
/***Search bar***/ 

  #myInput {
    background-image: url('/css/searchicon.png'); /* Add a search icon to input */
    background-position: 10px 12px; /* Position the search icon */
    background-repeat: no-repeat; /* Do not repeat the icon image */
    margin-left:10%;
    width: 74%;
    font-size: 16px; /* Increase font-size */
    padding: 12px 20px 12px 40px; /* Add some padding */
    border: 1px solid #ddd; /* Add a grey border */
    margin-bottom: 12px; /* Add some space below the input */
  }
  
  #myUL {
    /* Remove default list styling */
    list-style-type: none;
    padding: 0;
    margin: 0;
    margin-left: 10%;
    margin-right: 10%;
  }
  
  #myUL li a {
    /***
    border: 1px solid #ddd; /* Add a border to all links */
    margin-top: -1px; /* Prevent double borders */
    background-color: white; /* Grey background color */
    padding: 15px; /* Add some padding */
    text-decoration: none; /* Remove default text underline */
    font-size: 20px; /* Increase the font-size */
    color: #1167b1; /* Add a black text color */
    display: block; /* Make it into a block element to fill the whole list */
  }
  
  #myUL li a:hover:not(.header) {
    background-color: #eee; /* Add a hover effect to all links, except for headers */
  }
  
  #myUL li a .highlighted {
    background-color: yellow;
  }
  /***
  @media screen and (max-width: 768px) {
    .hero-container {
      grid-template-columns: 1fr;
    }
  }
  ***/
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="Styles1.css">
</head>
<body>
  <script src="scripts.js"></script>
  <div >
  <nav>
    <div >Nexamp</div>
    <div >
      <a href="/">Home</a> <a href="/">About</a> <a href="/">Contact</a>
    </div>
  </nav>
  <div class = "Main-Items">
   <strong>Collections:</strong>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
   <a href=espn.com>Animations</a>
  </div>
  <section >

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">

<ul id="myUL">
  <li><a href="#">Community Solar</a></li>
  <li><a href="#">Organic</a></li>

  <li><a href="#">Company Organization</a></li>
  <li><a href="#">Bob</a></li>

  <li><a href="#">Calvin</a></li>
  <li><a href="#">Christina</a></li>
  <li><a href="#">Cindy</a></li>
</ul>
  </section>
 </div>
</body>
</html>

CodePudding user response:

function myFunction() {
    const inputValue = document.getElementById("myInput").value;
    const listItems = document.querySelector("#myUL").querySelectorAll("li");
    if (!inputValue) {
      listItems.forEach((li) => (li.querySelector("a").style.color = "#1167b1"));
      return;
    }
    listItems.forEach((li) => {
      const child = li.querySelector("a");
      const txtValue = child.innerText;
      child.style.color =txtValue.toUpperCase().indexOf(inputValue.toUpperCase()) > -1
          ? "green"
          : "#1167b1";
    });
  }

Just replace with this and everything will work perfect.

CodePudding user response:

Here's a simple text highlight solution https://codepen.io/mkorostoff/pen/abLBOqd. You can just plug it in to your onkeyup function. You might also enjoy https://github.com/este/highlight-text which does the same thing, but case insensitive.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style type="text/css">.highlight {background-color: lightblue;}</style>
  <title></title>
</head>
<body>
<div><strong>Search term: </strong>cat</div>
<div >cat</div>
<div >catthew</div>
<div >cathy</div>
<div >calgury</div>
<div >camel</div>
<div >doja cat</div>
<div >uncatagorized</div>

<script>
  let searchTerm = 'cat';
  let highlight = `<span >${searchTerm}</span>`;
  let searchResults = document.querySelectorAll('.search-result');
  searchResults.forEach((searchResult) => {
    let text = searchResult.innerHTML;
    if (text === searchTerm) {
      text = highlight;
    }
    else {
      let parts = text.split(searchTerm);
      let newParts = [];
      parts.forEach((part) => {
        if (part === '') {
          newParts.push(`<span >${searchTerm}</span>`)
        }
        else newParts.push(part);
      });
      text = newParts.join('');
    }
    searchResult.innerHTML = text;
  })
</script>
</body>
</html>

  • Related