Home > other >  Text Input filter not initalizing?
Text Input filter not initalizing?

Time:01-27

I am practicing using loops to manipulate with data on my index.html. I am currently trying to filter an input text field where it will show data while the user types and hide the rest of the data.

//adds input elements
    let search = document.getElementById('search'); 
    search.addEventListener('keyup', filterNames); 



//Grabs information in ul and li
function filterNames (){
    let filterValue = document.getElementById('filterNames'); 
    let ul =  document.getElementById ('names'); 
    let li = ul.querySelectorAll('li.name-item'); 
    //loop for collection of items
    for (let i = 0; i < li.length; i  ) {
        let a = li[i].getElementByTagName('a') [0];
        // if statement for loop 
        if (a.innerHTML.toUpperCase().indexOf(filterValue) > -1){
            li[i].style.display=' '; 
        } else {
            li[i].style.display='none'; 
        }
    }
}
<div >
            <input type="text" id="search" placeholder="Search Name...">  
            <ul  id="names">
                <li ><a href="#"><h3>Mario</h3></a></li>
                <li ><a href="#"><h3>Link</h3></a></li></li>
                <li ><a href="#"><h3>Zelda</h3></a></li></li>
                <li ><a href="#"><h3>Bowser</h3></a></li></li>
                <li ><a href="#"><h3>Kratos</h3></a></li></li>
                <li ><a href="#"><h3>Yoshi</h3></a></li></li>
            </ul>
      </div>

CodePudding user response:

You can call forEach on the result of querySelectorAll. Just loop over each <li> and toggle a class i.e. .hidden instead of modifying the DOM. Also, the string object has an includes method.

const filterNameList = ({ target: { value } }) => {
  const query = value.trim().toLowerCase();  
  document.querySelectorAll('#names li').forEach(li => {
    const curr = li.textContent.trim().toLowerCase();
    const show = !query || (query && curr.includes(query));
    li.classList.toggle('hidden', !show);
  });
};

const searchEl = document.getElementById('search');
searchEl.addEventListener('keyup', filterNameList);
.hidden { display: none; }
<div >
  <input type="text" id="search" placeholder="Search Name..." autocomplete="off">
  <ul  id="names">
    <li >  <a href="#"> <h3>Mario</h3>  </a> </li>
    <li >   <a href="#"> <h3>Link</h3>   </a> </li>
    <li >  <a href="#"> <h3>Zelda</h3>  </a> </li>
    <li > <a href="#"> <h3>Bowser</h3> </a> </li>
    <li > <a href="#"> <h3>Kratos</h3> </a> </li>
    <li >  <a href="#"> <h3>Yoshi</h3>  </a> </li>
  </ul>
</div>

If you want to stick to a for-loop, you can simply modify the above script like so:

const filterNameList = ({ target: { value } }) => {
  const query = value.trim().toLowerCase();  
  const items = document.querySelectorAll('#names li');
  
  for (let i = 0; i < items.length; i  ) {
    const li = items[i];
    const curr = li.textContent.trim().toLowerCase();
    const show = !query || (query && curr.includes(query));
    li.classList.toggle('hidden', !show);
  }
};

const searchEl = document.getElementById('search');
searchEl.addEventListener('keyup', filterNameList);
.hidden { display: none; }
<div >
  <input type="text" id="search" placeholder="Search Name..." autocomplete="off">
  <ul  id="names">
    <li >  <a href="#"> <h3>Mario</h3>  </a> </li>
    <li >   <a href="#"> <h3>Link</h3>   </a> </li>
    <li >  <a href="#"> <h3>Zelda</h3>  </a> </li>
    <li > <a href="#"> <h3>Bowser</h3> </a> </li>
    <li > <a href="#"> <h3>Kratos</h3> </a> </li>
    <li >  <a href="#"> <h3>Yoshi</h3>  </a> </li>
  </ul>
</div>

  •  Tags:  
  • Related