Sorting through a table based on the name of the element

I am currently working on filtering an HTML table using a search form. It's working great, but I'm facing an issue where the filtered elements are trying to fill the entire width of the table instead of maintaining their original width (which is 25% of the table's width, excluding the spaces between the cells).

function searchFilter () {
   const input = document.getElementById('myInput');
   const filter = input.value.toUpperCase();
   const table = document.getElementById('tablaPiola');
   const articule = table.getElementsByTagName('td');

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

document.getElementById("filter-btn").addEventListener("click", searchFilter);
body {
background-color: black;
}

table
{border-spacing: 20px;
table-layout: fixed;
width: 600px;
margin: auto;
margin-top: 10px;}

td
{text-align: center;
border-radius: 10px;}

td a
{width: 100%;
display: block;
line-height: 50px;
text-decoration: none;
font-family: "Poppins";
font-weight: 700;
font-size: 12px;
color: white;}

.automatizaciones
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}

.bpm_a_ms
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}

.compresion
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}

.compresion_multibanda
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}
<input type="text" id="myInput">
<input type="button" id="filter-btn" value="Apply">
<table class="tabla_basico" id="tablaPiola">
   <tr>
      <td class="automatizaciones">
         <div class="overlay_basico"><a href="/">AUTOMATIZACIONES</a></div>
      </td>
      <td class="bpm_a_ms">
         <div class="overlay_intermedio"><a href="/">BPM A MS</a></div>
      </td>
      <td class="compresion">
         <div class="overlay_basico"><a href="compresion.html">COMPRESIÓN</a></div>
      </td>
      <td class="compresion_multibanda">
         <div class="overlay_intermedio"><a href="/">COMPRESIÓN MULTIBANDA</a></div>
       </td>
   </tr>
</table>

Check out my webpage

See how the filtering works

Answer №1

Initially, I considered using visibility: hidden but you pointed out that it would shift the visible elements to the left.

Another approach I thought of is adding padding cells at the end:

function searchFilter () {
   const input = document.getElementById('myInput');
   const filter = input.value.toUpperCase();
   const table = document.getElementById('tablaPiola');
   // Remove any fillers we added last time
   table.querySelectorAll(".filler").forEach(filler => {
       filler.parentNode.removeChild(filler);
   });
   const articule = table.getElementsByTagName('td');
   // Keep track of the number of visible cells at the end
   let showing = 0;

   for (i = 0; i < articule.length; i++) {
      a = articule[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
         articule[i].style.display = "";
         ++showing; // Record that this cell is visible
      } else {
         articule[i].style.display = "none";
      }
   }
   // Get the total number of cells (since `articule` is a live list)
   const max = articule.length;
   // Add blank cells to the end
   while (showing < max) {
      const filler = document.createElement("td");
      filler.className = "filler";
      table.appendChild(filler);
      ++showing;
   }
}

Live Example:

function searchFilter () {
   const input = document.getElementById('myInput');
   const filter = input.value.toUpperCase();
   const table = document.getElementById('tablaPiola');
   // Remove any fillers we added last time
   table.querySelectorAll(".filler").forEach(filler => {
       filler.parentNode.removeChild(filler);
   });
   const articule = table.getElementsByTagName('td');
   // Keep track of the number of visible cells at the end
   let showing = 0;
   
   for (i = 0; i < articule.length; i++) {
      a = articule[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
         articule[i].style.display = "";
         ++showing; // Record that this cell is visible
      } else {
         articule[i].style.display = "none";
      }
   }
   // Get the total number of cells (since `articule` is a live list)
   const max = articule.length;
   // Add blank cells to the end
   while (showing < max) {
      const filler = document.createElement("td");
      filler.className = "filler";
      table.appendChild(filler);
      ++showing;
   }
}

document.getElementById("filter-btn").addEventListener("click", searchFilter);
body {
background-color: black;
}

table
{border-spacing: 20px;
table-layout: fixed;
width: 1200px;
margin: auto;
margin-top: 100px;}

td
{text-align: center;
border-radius: 10px;}

td a
{width: 100%;
display: block;
line-height: 150px;
text-decoration: none;
font-family: "Poppins";
font-weight: 700;
font-size: 17.5px;
color: white;}

.automatizaciones
{background-image: url(imagenes/basico/automatizaciones/articulo.jpg);
background-size: cover;}

.bpm_a_ms
{background-image: url(imagenes/intermedio/bpm_a_ms/articulo.jpg);
background-size: cover;}

.compresion
{background-image: url(imagenes/basico/compresion/articulo.jpg);
background-size: cover;}

.compresion_multibanda
{background-image: url(imagenes/intermedio/compresion_multibanda/articulo.jpg);
background-size: cover;}
<input type="text" id="myInput">
<input type="button" id="filter-btn" value="Apply">
<table class="tabla_basico" id="tablaPiola">
   <tr>
      <td class="automatizaciones">
         <div class="overlay_basico"><a href="/">AUTOMATIZACIONES</a></div>
      </td>
      <td class="bpm_a_ms">
         <div class="overlay_intermedio"><a href="/">BPM A MS</a></div>
      </td>
      <td class="compresion">
         <div class="overlay_basico"><a href="compresion.html">COMPRESIÓN</a></div>
      </td>
      <td class="compresion_multibanda">
         <div class="overlay_intermedio"><a href="/">COMPRESIÓN MULTIBANDA</a></div>
       </td>
   </tr>
</table>


Some additional points not directly related to the main issue:

  • The code mentioned suffers from what I refer to as The Horror of Implicit Globals. Variables like i, a, or txtValue are not declared, leading to the creation of global variables inadvertently. I suggest using strict mode in all scripts to avoid this issue.

  • Interestingly, ES2015+ features are utilized in the code (e.g., const), so a for-of loop could be employed instead of a traditional for loop for brevity. However, it might be necessary to polyfill iterability on certain platforms. Refer to my response here for guidance on that.

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

VSCODE's intellisense feature seems to be ignoring CSS code within JSX files

I've been puzzling over why Visual Studio Code isn't recognizing CSS syntax inside JSX files. While I'm typing, CSS IntelliSense doesn't provide suggestions for CSS - only Emmet suggestions.https://i.stack.imgur.com/FegYO.png Despite t ...

The exported NextJS URL isn't functioning properly

Recently, I delved into the world of Next JS by following a tutorial on YouTube by Brad Traversy. In his guidance, I used next export to export the program and ran it using serve -s out -p 8000. While the page loads perfectly on localhost:8000, the issue a ...

Incorporating a switch button for toggling functionality in a Rails application

I attempted to convert a select tag into a JavaScript toggle on/off switch within my Rails application. After some searching, I came across a straightforward solution on the W3Schools website. http://www.w3schools.com/jquerymobile/tryit.asp?filename=tryj ...

Executing <script> tags inside <template> on vue js

I have encountered a problem while trying to add an Iframe from a service I am using. The content comes within script tags, but when I try to insert them into Vue 3 framework, I encounter an error. I have searched for a solution and came across a thread o ...

Unable to display content within a map function

I am facing an issue with a map function in my code. The function is supposed to return a component with deconstructed properties. While the map itself is functioning correctly and I can see all the right values when I log them to the console, nothing is g ...

Material UI defaults remain unchanged despite any emotional influence

I'm currently experimenting with custom styling on a MaterialUI Typography component using the code snippet below: const StyledTitleTypography = styled(Typography)` color: 'black'; font-weight: 'bold'; `; <StyledTitleTypogr ...

Creating a custom Chrome extension with CSS embedded within an iframe

Recently, I developed a Chrome app that includes an iframe element within it. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="v ...

Center-align the text within the dropdown menu

Here is the HTML code snippet I am working on: <select id="ddlCountry" placeholder="optional" class="select" title="Select Country"> <option value="0">country</option> </select> This is how the CSS is set up: .select { width ...

The hover effect fails to function properly after altering the background color. The default color setting is transparent

<button class="button-main slide">Slide Left</button> .button-main{ color: black; outline: none; background: transparent; border: none; letter-spacing: 0.0625em; padding: 8px 10px; text-transform: uppercase; font: b ...

Generate final string output from compiled template

Check out this template I created: <script type="text/ng-template" id="validationErrors.html"> <div id="validationErrors"> <div id="errorListContainer"> <h2>Your order has some errors:</h2> ...

Unique: "Unique One-Step Deviation in Date Comparison"

A Little Background Information: I am working with data points that span from the current day to 5 days ahead, in 3-hour intervals (such as 10pm, 1am, 4am, 7am...). My goal is to organize these data points into arrays sorted by date, with each array repre ...

Using ngrx to automatically update data upon subscription

Background The technology stack I am using for my application includes Angular 4.x, ngrx 4.x, and rxjs 5.4.x. Data is retrieved from a websocket as well as a RESTful API in order to share it between multiple components through ngrx. Currently, data is ref ...

Tips for adjusting image dimensions with url() method in css

I have successfully incorporated collapsible functionality on my page. I would like to display a down arrow image instead of the default '+' symbol on the right side of the collapsible section. To achieve this, I can use the following CSS code s ...

How to position the close (X) button on the corner of an image within a CSS grid

I have a collection of images with varying sizes and ratios in a responsive CSS grid layout. Each image needs to have a close button located at the top-right corner. To achieve this, I have inserted a form within each grid cell with a button and an image i ...

What is the method for inserting data into an array of objects in JavaScript?

I have a question regarding how to push/replace data into an object of an array of objects. Please excuse any mistakes in my grammar. Here is my dummy data: const dummyData = { id: 1, daerah: "Bandung", date:"1668790800000& ...

Retrieve JSON data generated within a JavaScript-powered webpage

My issue involves two HTML pages: 1) The first HTML Page (page1.html): <html lang="en"> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script> <script type="text/ ...

Why is the second row of inputs not displaying in Vue.js?

I am currently developing a Single Page Application (SPA) that includes options with variants, similar to the image shown below: [1]: https://i.sstatic.net/82I5U.png However, I have encountered an issue where the second row of inputs for variants is not b ...

I have successfully implemented an onChange function with its corresponding set of parameters. However, I now desire to extend its functionality by incorporating

I have an onchange function that triggers when the "pending" option is selected in a select dropdown menu. This function adds a predefined value to an input field. However, I also want this functionality to apply when the page loads. Currently, the "pendin ...

What is the best way to modify a variable in a nested element using ng-click in the parent element?

Review this code snippet: <section class="page-section about-us" scroll-bookmark="about-us" ng-click="activeSection=true" ng-init="activeSection=false"> <div class="page-content sub-content active-section">{{activeSection}} < ...

"Here's how you can mark an option as selected in Angular, either from the component or the HTML file

When it comes to my form, I have a select menu that sends data to an SQL database and then fetches it back when it is called for editing. The value being edited should be displayed in the select menu option as selected. Here's a peek at my code: < ...