0

I want to make a search filter bar for a list and I figured out how to di it, but the examples are all using get elements by ID. I need to use it in multiple places so I want to change it to get elements by class.

I looked up how to get element by ID for filtering list, and I want to convert that to get element by Class. I looked up how to do it but it didn't seem to work. It should be as simple as changing getElementByID to getElementsByClassName right?

here's my code

    <input type="text" class="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<ul class="myUL">
  <li><a href="#">Adele</a></li>
  <li><a href="#">Agnes</a></li>

  <li><a href="#">Billy</a></li>
  <li><a href="#">Bob</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, txtValue;
    input = document.getElementsByClassName('myInput');
    filter = input.value.toUpperCase();
    ul = document.getElementsByClassName('myUL');
    li = ul.getElementsByTagName("li");
    for (i = 0; i < li.length; i++) {
        a = li[i].getElementsByTagName("a")[0];
        txtValue = a.textContent || a.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
            li[i].style.display = "";
        } else {
            li[i].style.display = "none";
        }
    }
}
</script>

when I run it in codepen with get elements by ID, it works fine, but it broke when I switched to class. Any idea what's wrong?

wswswswsws
  • 41
  • 1
  • 8

1 Answers1

0

getElementsByClassNames returns multiple elements and same for getElementsByTagName, so you have to loop over the elements. See my code snippet, it's working.

function myFunction() {
  var input, filter, ul, li, a, i, txtValue;
  const inputs = [...document.getElementsByClassName('myInput')];
  inputs.forEach(input => {
    filter = input.value.toUpperCase();
    const uls = [...document.getElementsByClassName('myUL')];
    uls.forEach(ul => {
      li = ul.getElementsByTagName("li");
      for (i = 0; i < li.length; i++) {
        a = li[i].getElementsByTagName("a")[0];
        txtValue = a.textContent || a.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
          li[i].style.display = "";
        } else {
          li[i].style.display = "none";
        }
      }
    })
  })
}
<input type="text" class="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

<ul class="myUL">
  <li><a href="#">Adele</a></li>
  <li><a href="#">Agnes</a></li>

  <li><a href="#">Billy</a></li>
  <li><a href="#">Bob</a></li>

  <li><a href="#">Calvin</a></li>
  <li><a href="#">Christina</a></li>
  <li><a href="#">Cindy</a></li>
</ul>
Shridhar Sharma
  • 2,337
  • 1
  • 9
  • 13
  • 2
    If you see a comment with "Does this answer your question?" followed by a link to a question, please look at the answers to that linked question and see if they answer the question. If so, please do not answer the question. – Heretic Monkey Oct 06 '20 at 17:54