JavaScript table search feature for novices - finding results

I am relatively new to this, but I am working on improving the workflow within my company. I found some code at this link in order to create an internal site for searching current part numbers. However, my employees are looking for parts based on descriptions, and the JavaScript provided only searches for exact matches rather than individual words.

For instance, with the existing code, a search for "Trading Island" should yield the same results as a search for "Island Trading." I know it's possible, but I'm struggling to implement it successfully.

<!DOCTYPE html>
<html>
<head>
<style>
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th, #myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header, #myTable tr:hover {
  background-color: #f1f1f1;
}
</style>
</head>
<body>

<h2>Customer Info</h2>

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

<table id="myTable">
  <tr class="header">
    <th style="width:60%;">Name</th>
    <th style="width:40%;">Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbkop</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Italy</td>
  </tr>
  <tr>
    <td>North/South</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Paris specialites</td>
    <td>France</td>
  </tr>
</table>

<script>
function filterResults() {
  var input, filter, table, row, cell, i;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  row = table.getElementsByTagName("tr");
  for (i = 0; i < row.length; i++) {
    cell = row[i].getElementsByTagName("td")[0];
    if (cell) {
      if (cell.innerHTML.toUpperCase().indexOf(filter) > -1) {
        row[i].style.display = "";
      } else {
        row[i].style.display = "none";
      }
    }       
  }
}
</script>

</body>
</html>

Answer №1

For optimized word matching, it is advisable to store the search query in an array and break down the cell contents into another array.

You can then easily utilize either the Array.prototype.every() method or the Array.prototype.some() method to check if all or some of the search words are present in the cell content.

Refer to the included comments for further insights.

// Accessing the input field
var searchElement = document.getElementById("myInput");

// Attaching the element to an event handler:
searchElement.addEventListener("keyup", search);

// Event handler function:
function search(){

  // Breaking down the search input into an array of words by splitting at spaces using a regular expression.
  // Additionally, converting all strings to lowercase for case-insensitive matching.
  var searchWords = searchElement.value.toLowerCase().split(/\s+/);

  // Displaying individual search words
  //console.clear();
  //console.log(searchWords);

  // Creating an array of all cells which will serve as our data source:
  var theCells = document.querySelectorAll("td");

  // Iterating over each cell
  theCells.forEach(function(cell){
    // Resetting any previous matches
    cell.style.backgroundColor = "inherit";
    
    // Extracting words from the cell text as an array (converting to lowercase for matching)
    var cellWords = cell.textContent.toLowerCase().split(/\s+/);

    // Checking if the cell contains all search words (Use "some" instead of "every" to check if the cell has at least one search word)
    var result = cellWords.every(elem => searchWords.indexOf(elem) > -1);
    
    // The every and some methods return a boolean indicating if the condition was met:
    if(result){
      console.clear();
      console.log("Match found in: " + cell.textContent);
      cell.style.backgroundColor = "#ff0";
    }
  
  });
  
}
<input type="text" id="myInput" placeholder="Search for names.." title="Type in a name">

<table id="myTable">
  <tr class="header">
    <th style="width:60%;">Name</th>
    <th style="width:40%;">Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbkop</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Italy</td>
  </tr>
  <tr>
    <td>North/South</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Paris specialites</td>
    <td>France</td>
  </tr>
</table>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to simultaneously apply the :active pseudoclass to multiple elements?

<div id="a">A</div> <div id="b">B</div> <div id="c">C</div> <style> #a, #b, #c { height: 100px; width: 100px; background-color:red; font-size: 100px; margin-bottom: 20px; } ...

Move a 'square' to a different page and display it in a grid format after clicking a button

I am currently developing a project that allows students or schools to add projects and search for collaborators. On a specific page, users can input project details with a preview square next to the fields for visualization. Once the user uploads the ...

Activating a link without clicking will not trigger any javascript functions

I have been attempting to display an image when I hover over a link, but for some reason, the .hover() event is not functioning as expected. Initially, I am just aiming to have an alert pop up. Once I have that working, I can proceed with fading elements i ...

Learn how to send information to a form and receive a response when a key is pressed, either up or down, by

Can you help with fetching data and passing it into a form to respond to customer names on keyup or keydown using JSON and PHP? <?php $conn = new mysqli("localhost", 'root', "", "laravel"); $query = mysqli_query($conn,"select * from customers ...

Steps for iterating through an array within an object

I currently have a JavaScript object with an array included: { id: 1, title: "Looping through arrays", tags: ["array", "forEach", "map"] } When trying to loop through the object, I am using the following ...

The Autocomplete feature in Material UI is failing to function properly when paired with a

I have a requirement to customize the Autocomplete Highlight feature provided in a specific example to suit my project needs. (Link: Material UI Autocomplete Documentation) The original Highlight example includes borders which I removed by referring to th ...

Convert HTML form input into a JSON file for safekeeping

<div class="email"> <section class="subscribe"> <div class="subscribe-pitch"> </div> <form action="#" method="post" class="subscribe-form" id="emails_form"> <input type="email" class="subscribe-input" placeholder="Enter ema ...

The command 'create-react-app' is not valid and cannot be recognized as an internal or external command, operable program, or batch file

I've been struggling to set up a React project, as the create-react-app my-app command doesn't seem to be working. Can anyone offer some assistance? Here are the commands I'm using: npm install -g create-react-app create-react-app my-app ...

Fetching all data from a SQLite database in a Listview using React Native

I have been utilizing the library found at https://github.com/andpor/react-native-sqlite-storage in my react native project. To retrieve a single row from the database, I use the following code: db.transaction((tx) => { tx.executeSql('SEL ...

The Ajax script is malfunctioning

Currently, I have a program that requires the user to input a city and country. The program then checks the database to see if the city already exists - displaying a warning message using ajax if it does, or adding the city to the database if it doesn&apos ...

show tab focus outline only

In search of a straightforward and effective method for focusable elements to display an outline only when the tab key is pressed, without showing it when using a mouse in React applications. (looking for something similar to :focus-visible that function ...

Tips for capturing changes in a "count" variable and executing actions based on its value

I have a counter on my webpage and I'm trying to change the style of an element based on the count variable. I tried using the .change action but I haven't been able to get it working. It might not be the right solution. Can anyone provide some ...

Steps for converting an HTML form into a sophisticated JavaScript object

Is it possible to transform a form into a complex JavaScript object based on a structured form layout? I am not sure if there is a better way to accomplish this, but essentially what I am looking for is the following scenario: <form> <input n ...

Optimizing Wordpress by Efficiently Enqueueing Javascript

As a beginner with a WordPress website, I am aware that in order to execute scripts on a WordPress page, they need to be enqueued in the functions.php file. However, I'm unsure about the correct process for this. The specific JavaScript file I want t ...

Is it possible for a MySQL loop to only delete the first entry?

My MySQL looping is not working properly when I click the second button to get their id and continue with the rest of the process. Why is this happening? $(document).ready(function() { $("#deleteSchedule").click(function (e) { e.preventDefault(); ...

Generate real-time dynamic line charts using data pulled directly from a MySQL database

I am in search of guidance on developing a real-time line chart that can dynamically update based on data fetched from MySQL. I need an example or reference on how to achieve this functionality without having to refresh the webpage every time new data is ...

Does ng-include fetch the included HTML files individually or merge them into a single HTML file before serving?

Is there a performance impact when using the ng-include Angular directive, in terms of having included HTML files downloaded as separate entities to the user's browsers? I am utilizing a CDN like AWS CloudFront instead of a node server to serve the H ...

What is the best way to attach an attribute to a element created dynamically in Angular2+?

After reviewing resources like this and this, I've run into issues trying to set attributes on dynamically generated elements within a custom component (<c-tabs>). Relevant Elements https://i.stack.imgur.com/9HoC2.png HTML <c-tabs #mainCom ...

The switch switches on yet another switch

Greetings everyone, Currently, I am in the midst of my exam project and creating a mobile menu. The functionality is there, but unfortunately, when closing the menu, it also triggers the search toggle which displays an unwanted div, becoming quite botherso ...

What is the order of reflection in dynamic classes - are they added to the beginning or

Just a general question here: If dynamic classes are added to an element (e.g. through a jQuery-ui add-on), and the element already has classes, does the dynamically added class get appended or prepended to the list of classes? The reason for my question ...