Kimura
Kimura

Reputation: 17

Detecting if a list is empty

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

Answers (3)

user2345
user2345

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
}

EDIT

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

gyre
gyre

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

Punit
Punit

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

Related Questions