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>