Reputation: 17
I'm using w3School's tutorial to create a filter list. I was wondering if there was a way to check when the list is empty and to execute a function and also when there is something in the list and to execute a function. Is it possible? Thanks.
Upvotes: 0
Views: 264
Reputation: 3227
You could use querySelectorAll
to get all the li
, and then check how much there are.
if(document.querySelectorAll("#myUL li").length === 0) {
// The list is empty
} else {
// The list is not empty
}
As Punit noticed (see comments of this answer), li
elements are not deleted but hidden.
To execute a function or not after a search if the list is empty or not, the easiest way would be to modify the for
loop to add a variable that stores the number of results:
var foundCount = 0;
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
foundCount++; // Increment the count
} else {
li[i].style.display = "none";
}
}
And then test the foundCount
variable:
if(foundCount === 0) {
// List is empty
} else {
// There is at least one element
}
Upvotes: 2
Reputation: 16779
If you want to know only whether or not the list is empty, you can check whether its height is zero:
if (document.getElementById('myUL').clientHeight)) {
console.log('The list contains at least one element.')
} else {
console.log('The list is empty.')
}
If you would like a more precise count of the number of visible elements, you can use a similar strategy and take advantage of the fact that (in your case) all list elements are the same height. The number of visible items is simply the ratio of the height of the list to the height of an item.
var ul = document.getElementById('myUL'),
itemHeight = ul.firstElementChild.clientHeight
function getVisibleItemCount() {
return Math.round(ul.clientHeight / itemHeight)
}
document.getElementById('myInput').addEventListener('keyup', function() {
console.log(getVisibleItemCount())
})
<!-- Tutorial Source: http://www.w3schools.com/howto/howto_js_filter_lists.asp -->
<!DOCTYPE html>
<html>
<head>
<style>
* {
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.header {
background-color: #e2e2e2;
cursor: default;
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
</style>
</head>
<body>
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL">
<li><a href="#" class="header">A</a>
</li>
<li><a href="#">Adele</a>
</li>
<li><a href="#">Agnes</a>
</li>
<li><a href="#" class="header">B</a>
</li>
<li><a href="#">Billy</a>
</li>
<li><a href="#">Bob</a>
</li>
<li><a href="#" class="header">C</a>
</li>
<li><a href="#">Calvin</a>
</li>
<li><a href="#">Christina</a>
</li>
<li><a href="#">Cindy</a>
</li>
</ul>
<script>
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++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
</script>
</body>
</html>
Upvotes: 0
Reputation: 1976
I copied the code from the tutorial to this snippet.
It's as simple as having a count
variable and incrementing it when the search query is matched, then checking if count
is 0.
function myFunction() {
// Declare variables
var input, filter, ul, li, a, i, count;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName('li');
count = 0;
// 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];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
count++;
} else {
li[i].style.display = "none";
}
}
console.log(count);
if (count > 0) {
// one or more names
} else {
// no names
}
}
#myInput {
width: 100%;
/* Full-width */
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;
}
#myUL li a {
border: 1px solid #ddd;
/* Add a border to all links */
margin-top: -1px;
/* Prevent double borders */
background-color: #f6f6f6;
/* Grey background color */
padding: 12px;
/* Add some padding */
text-decoration: none;
/* Remove default text underline */
font-size: 18px;
/* Increase the font-size */
color: black;
/* Add a black text color */
display: block;
/* Make it into a block element to fill the whole list */
}
#myUL li a.header {
background-color: #e2e2e2;
/* Add a darker background color for headers */
cursor: default;
/* Change cursor style */
}
#myUL li a:hover:not(.header) {
background-color: #eee;
/* Add a hover effect to all links, except for headers */
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<ul id="myUL">
<li><a href="#" class="header">A</a>
</li>
<li><a href="#">Adele</a>
</li>
<li><a href="#">Agnes</a>
</li>
<li><a href="#" class="header">B</a>
</li>
<li><a href="#">Billy</a>
</li>
<li><a href="#">Bob</a>
</li>
<li><a href="#" class="header">C</a>
</li>
<li><a href="#">Calvin</a>
</li>
<li><a href="#">Christina</a>
</li>
<li><a href="#">Cindy</a>
</li>
</ul>
Upvotes: 1