Reputation: 218
I need to search content based on the input provided. For eg) if i provide k as input it should filter the content and show names akila and place uk. Problem faced here is first element is being filtered.Html elements are stacked as shown in the below code
function myFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
//console.log(li[i].children)
a = li[i].getElementsByTagName("span")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL">
<li>
<a href="#">Names</a>
<!--ul id 1-->
<ul id="corp">
<li><a href="#"><div><span>akila</span></div></a></li>
<li><a href="#"><div><span>agnes</span></div></a></li>
</ul>
</li>
<li>
<a href="#">Place</a>
<!--ul id 2-->
<ul id="region">
<li><a href="#"><div><span>USA</span></div></a></li>
<li><a href="#"><div><span>UK</span></div></a></li>
</ul>
</li>
</ul>
Upvotes: 0
Views: 105
Reputation: 655
The problem is - you are selecting too many li
elements and applying your css changes (hiding/displaying) to some of the li
elements that you should not.
Here is fixed and refactored code that works based on your requirements. However it is not clear from your question whether or not the list is dynamically generated.
If it is dynamically generated - then the logic for getting all li
should happen right after the list being generated, not every time you change your filter input.
If it is a static list - the other answer has a better solution of selecting li
elements based on ids. Yet you should build the list when the script is loaded, not every time you change the filter input.
I broke functionality into separate functions.
function filter_input(key, targetEl, el) {
if (targetEl.innerText.toUpperCase().indexOf(key) > -1) {
el.style.display = "";
} else {
el.style.display = "none";
}
}
function filterAll(all_li, filter){
for (i = 0; i < all_li.length; i++) {
var span = all_li[i].getElementsByTagName("span")[0];
filter_input(filter, span, all_li[i]);
}
}
function buildList() {
var ul, li, a, i, major_list, all_li;
ul = document.getElementById("myUL");
major_list = ul.getElementsByTagName("ul");
all_li = [];
for (j = 0; j < major_list.length; j++) {
var minor_list = major_list[j].getElementsByTagName("li");
for (x = 0; x < minor_list.length; x++) {
all_li.push(minor_list[x]);
}
}
return all_li;
}
function myFunction() {
var input, filter;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
filterAll(buildList(), filter);
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL">
<li>
<a href="#">Names</a>
<!--ul id 1-->
<ul id="corp">
<li><a href="#"><div><span>akila</span></div></a></li>
<li><a href="#"><div><span>agnes</span></div></a></li>
</ul>
</li>
<li>
<a href="#">Place</a>
<!--ul id 2-->
<ul id="region">
<li><a href="#"><div><span>USA</span></div></a></li>
<li><a href="#"><div><span>UK</span></div></a></li>
</ul>
</li>
</ul>
Upvotes: 1
Reputation: 547
The problem is that the line li = ul.getElementsByTagName("li");
returns the <li>
that contain the <ul>
It should only return <li>
that are either names or places
Here is the updated code (with comments of the problem/fix):
function myFunction() {
var input, filter, li, a, i; // removed ul variable
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
li = document.querySelectorAll("#corp li, #region li"); // get only li elements that are names or places
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("span")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL">
<li> <!-- Your code was also returning this li -->
<a href="#">Names</a>
<ul id="corp">
<li><a href="#"><div><span>akila</span></div></a></li>
<li><a href="#"><div><span>agnes</span></div></a></li>
</ul>
</li>
<li> <!-- Your code was also returning this li -->
<a href="#">Place</a>
<ul id="region">
<li><a href="#"><div><span>USA</span></div></a></li>
<li><a href="#"><div><span>UK</span></div></a></li>
</ul>
</li>
</ul>
Upvotes: 1