Quickly Search and Filter a List With JavaScript

This tutorial demonstrates how to filter a list using JavaScript. When we search, JavaScript returns a match from an unordered list.

The article below will use a JavaScript filter function to implement dynamic filtering and search a list where similar names will be returned and non-matching results hidden. The function will search an unordered list element on a website, and the JavaScript will display matching values or similar terms from an unordered list containing first names. We’ll style the search bar, center it on a page with CSS, and then walk through adding JavaScript to create the searchable list. Before we begin this tutorial, let’s review some frequently asked questions about this subject.

What Is Filtering a List in JavaScript?

Filtering a list is a process we apply to ensure that only the data we want is returned or displayed. For example, the process of finding a word or sentence we are looking for in a PDF document is the CTRL+F command. Searching a web page, an input, or elements, using a word or phrase is an example of filtering and can be implemented using JavaScript.

How To Filter an Array With JavaScript?

One can use JavaScript’s filter() function to filter an array based on its values. The filter() function returns a new array containing all the elements that pass a given parameter function. Using the filter function, an array from elements on a page, such as lists, text fields, options, and other data, can be filtered if converted into an array.

What is filter() in JavaScript?

The filter() method in JavaScript creates a new array filled with elements that pass a simple or complex condition provided by a function. The first parameter takes a function name, an anonymous function, or none, and the second parameter takes an array variable as a value. Internally, the filter() method iterates over each array element and passes each value to a callback function. As the value passes or fails a condition in the function, filter() constructs a new array of all the elements for which the callback function returns a value that coerces to true. Array elements that do not pass a callback function are discarded and are not included in the new array.

It’s important to note whenever the filter() method is used; it does not change the original array, and a callback function is not executed on empty values.

Creating a Searchable Unordered List

Now that we have a brief understanding of filtering a list, we should create a working example. First, we must make an HTML web page that contains an input element with a search bar. Once we have a web page structure, input element, and search bar, we need to add values we can attach to the search bar as a data source. This is where we add an unordered list element that contains a long column of first names.

HTML

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link rel="stylesheet" href="style.css" />
      <title>Filter List</title>
   </head>
   <body>
      <input
         type="text"
         id="myInput"
         onkeyup="myFunction()"
         placeholder="Search for names.."
         />
      <ul id="myUL">
        <li>Adele</li>
        <li>Agnes</li>
        <li>Billy</li>
        <li>Bob</li>
        <li>Calvin</li>
        <li>Camille</li>
        <li>Christina</li>
        <li>Cindy</li>
        <li>David</li>
        <li>Davis</li>
        <li>Ethan</li>
        <li>Eric</li>
        <li>Elsa</li>
        <li>Frank</li>
        <li>Fiona</li>
        <li>George</li>
        <li>Gerald</li>
        <li>Galvin</li>
        <li>Harry</li>
        <li>Helen</li>
        <li>Horacio</li>
        <li>Isabelle</li>
        <li>Irina</li>
        <li>Iker</li>
        <li>John</li>
        <li>Joe</li>
        <li>Jane</li>
        <li>James</li>
        <li>Katherine</li>
        <li>Karen</li>
        <li>Lucas</li>
        <li>Laura</li>
        <li>Michael</li>
        <li>Marry</li>
        <li>Natalia</li>
        <li>Norman</li>
        <li>Ortiz</li>
        <li>Omar</li>
        <li>Pascal</li>
        <li>Penny</li>
      </ul>
      <script src="script.js"></script>
   </body>
</html>

Our next step is to add a little bit of design for the input and list elements we created. We will do this with CSS styles and properties. We use a CSS selector to select our input with an ID of #myInput and our list with the #myUL ID.

CSS

#myInput {
  /* Some CSS properties here */
}

#myUL {
  /* Adding even more CSS properties */
}

Below, the CSS styles for the project have comments next to the properties to explain what each property does.

html,
body {
  height: 100%;
  background: linear-gradient(
    to right bottom,
    #0b2750,
    #004268,
    #026068,
    #015a37,
    #425a0b
  );
  overflow: hidden;
  margin: 0;
}

#myInput {
  width: 100%; /* Full-width */
  font-size: 16px; /* Increase font-size */
  padding: 12px 15px 12px 15px; /* Add some padding */
  border: 1px solid #ddd; /* Add a grey border */
  margin-bottom: 12px; /* Add some space below the input */
  box-sizing: border-box;
  border-color: rgb(23 90 229 / 80%);
  outline: 0;
}

#myUL {
  /* Remove default list styling */
  list-style-type: none;
  padding: 0;
  margin: 0;
  height: 400px;
  overflow-y: scroll;
}

#myUL li {
  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 */
  cursor: pointer;
}

#myUL li:hover:not(.header) {
  background-color: #eee; /* Add a hover effect to all links, except for headers */
}

.container {
  width: 600px;
  margin: 0 auto;
  background: white;
  border-radius: 20px;
  box-shadow: 0 5px 5px rgb(0 0 0 / 49%);
  padding: 20px;
}

.super-container {
  width: 100%;
  background: transparent;
  text-align: center;
  -webkit-box-align: center !important;
  -ms-flex-align: center !important;
  align-items: center !important;
  -webkit-box-pack: center !important;
  -ms-flex-pack: center !important;
  justify-content: center !important;
  display: -webkit-box !important;
  display: -ms-flexbox !important;
  display: flex !important;
  height: 100%;
}

Retrieving the Data Source

Now that we have our webpage, elements, and styles, we can move on to giving functionality to a webpage so we can search the list. We will need to use JavaScript to create a function to do this.

First, we define our input, filter, ul, listElements, i, and txtValue variables.

var input, filter, ul, listElements, i, txtValue;

Next, we store the input field element as a value of the input variable.

input = document.getElementById("myInput");

We need to get the current value of the search bar by executing the value method on the input variable. Then we convert a search bar input to upper case to normalize the data. We use JavaScript toUpperCase() to uppercase the input. This uppercase helps us avoid not accurately matching our value against a data source. We store a transformed input value in a variable named filter.

filter = input.value.toUpperCase();

Next, we search and retrieve our unordered list element for ul’s value. This variable now contains a long of list names and we can set them as a value for li.

ul = document.getElementById("myUL");
listElements = ul.getElementsByTagName("li");

Once the variables are created and a list data source is set, we iterate over the list elements by using a loop for their length.

for (i = 0; i < listElements.length; i++) {
    txtValue = listElements[i].textContent || listElements[i].innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      listElements[i].style.display = "";
    } else {
      listElements[i].style.display = "none";
    }
}

Looping through the lists allows us to check each value, but we need to get the element’s text value before performing matching.

The txtValue variable in the loop is the text contents of the current list element. We use a logical operator to get a textContent or an innerText value, whichever returns a text value in the browser.

txtValue = listElements[i].textContent || listElements[i].innerText;

Note: A JavaScript logical OR (||) operator (logical disjunction) with a set of operands returns True when one or more of its conditions is True.

Matching the Data Source Items

After setting the txtValue variable, we transform the variable to upper case and check if the variable matches our search bar filter variable using an indexOf() JavaScript method.

txtValue.toUpperCase().indexOf(filter) > -1

Let’s briefly talk about the indexOf() method.

indexOf(filter)

The indexOf() method checks for an occurrence of a value in a string. If a value is not found, the method returns -1.

indexOf(filter) > -1

The indexOf() method is case-sensitive, which is why we use toUpperCase() method on txtValue.

txtValue.toUpperCase()

Hiding Non-matching Results

If txtValue.toUpperCase().indexOf(filter) returns 1, we keep the list item on the screen. We hide the list item elements if the txtValue does not match filter.

if (txtValue.toUpperCase().indexOf(filter) > -1) {
  listElements[i].style.display = "";
} else {
  listElements[i].style.display = "none";
}

When a list item does not match, we can set a display property to none on an element with a JavaScript style method. A display property allows us to make invisible values that do not match our input query.

listElements[i].style.display = "none";
Returning Similar Results in a JavaScript List Search
Returning Similar Results in a JavaScript List Search

The CSS display property set to none hides results we don’t want to see.

Hiding Non Matching Results in a JavaScript List Search
Hiding Non-Matching Results in a JavaScript List Search

Now that we explained each part of the JavaScript function. A function that filters an unordered list using a search bar can be summarized as a loop that goes through each list item and hides non-matching strings that don’t match a search query. Here is the complete JavaScript code for the project.

function myFunction() {
  //Declare variables
  var input, filter, ul, listElements, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  ul = document.getElementById("myUL");
  listElements = ul.getElementsByTagName("li");

  // Loop through all list items, and hide those who don't match the search query
  for (i = 0; i < listElements.length; i++) {
    txtValue = listElements[i].textContent || listElements[i].innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      listElements[i].style.display = "";
    } else {
      listElements[i].style.display = "none";
    }
  }
}

Running the Example

Running the example is easy; you’ll need HTML, CSS, and JavaScript from above to render the images below.

In the first image below, we will see the image of our application when it first runs. We have all the list items shown with a scrollbar.

Screen Output

JavaScript List Search
JavaScript List Search

Then we will test our application by trying to search for the name Camille; the JavaScript function attached to the search bar removes all the list items that don’t match the term typed in the search bar. In this case, we get an exact match for Camille.

Matched Result

JavaScript List Search With Results
JavaScript List Search With Results

Recommended Articles

Other Articles