Search list or filter list

I created a search list or filter list. But I want to add these features -

  1. Search lists will be hidden by default.
  2. When someone clicks on the search box, the search list seems to be hidden. When it starts typing in the search box and matches any text in the search list, it shows up.
  3. Texts that match will be bold.

I try to add many javascript functions but it doesn't work. If you know any alternative way please share.

function myFunction() {
    var input, filter, ul, li, a, i, txtValue;
    input = document.getElementById("myInput");
    filter = input.value.toUpperCase();
    ul = document.getElementById("myUL");
    li = ul.getElementsByTagName("li");
    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 = "";
        } else {
            li[i].style.display = "none";
        }
    }
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 12px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myUL {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

#myUL li a {
  border: 1px solid #ddd;
  margin-top: -1px; /* Prevent double borders */
  background-color: #f6f6f6;
  padding: 12px;
  text-decoration: none;
  font-size: 18px;
  color: black;
  display: block
}

#myUL li a:hover:not(.header) {
  background-color: #eee;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<ul id="myUL">
  <li><a href="#">Adele</a></li>
  <li><a href="#">Agnes</a></li>

  <li><a href="#">Billy</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>

Solution 1:

It was not clear whether or not the text that was to be made bold was only to be the portion of the string typed or the entire string so the below has a commente dout portion that makes the whole word bold. The alternative approach, using a datalist, needs no additional coding for basic functionality and is the more common approach to this type of problem on the interwebs.

function myFunction(e) {
  // find all `li` > a elements
  let col=document.querySelectorAll('ul#myUL li a');
      // iterate through all elements; re-hide & remove className from each.
      col.forEach(n=>{
      
        n.parentNode.style.display='none';
        n.classList.remove('bold');
        
        // if the typed value matches the beginning of a list item; display the text & assign Bold className
        if( this.value.length > 0 && this.value.trim()!='' && n.textContent.toLowerCase().startsWith( this.value.toLowerCase() ) ){
        
          n.parentNode.style.display='block';
          // make the whole word bold
          //n.classList.add('bold');
          
          // make the matched portion bold
          n.innerHTML = `<span class="bold">${this.value}</span>` + n.textContent.substr(this.value.length)
        }
      });
}



document.querySelector('input[name="search"]').addEventListener('keyup',myFunction);
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 12px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myUL {
  list-style-type: none;
  padding: 0;
  margin: 0;
}
#myUL li{
  display:none;
}

#myUL li a {
  border: 1px solid #ddd;
  margin-top: -1px; /* Prevent double borders */
  background-color: #f6f6f6;
  padding: 12px;
  text-decoration: none;
  font-size: 18px;
  color: black;
  display: block
}

#myUL li a:hover:not(.header) {
  background-color: #eee;
}

.bold{font-weight:bold;color:red
<h5>The original approach</h5>
<input name='search' type="text" placeholder="Search for names.." title="Type in a name" />
<ul id="myUL">
  <li><a href="#">Adele</a></li>
  <li><a href="#">Agnes</a></li>
  <li><a href="#">Billy</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>

<h5>An alternative involving no Javascript for a similar end result using a datalist</h5>
<input type='text' name='dlsearch' list='dls' />
<datalist id='dls'>
  <option>Adele
  <option>Agnes
  <option>Billy
  <option>Bob
  <option>Calvin
  <option>Christina
  <option>Cindy
</datalist>