Artículo original escrito por: Kingsley Ubah
Artículo original: How to Build a Responsive Form with Filter Functionality Using HTML, CSS, and JavaScript
Traducido y adaptado por: Ivan Rivalcoba con la colaboración de Janine Rodriguez

La gran mayoría de los sitios que muestran una lista de datos mediante una tabla típicamente implementan algún tipo de funcionalidad de filtrado de datos. Esto le permite al usuario filtrar los elementos relevantes de una lista en función de una entrada de texto proveniente de algún formulario.

En este breve tutorial vamos a construir una tabla responsiva que incorpora la funcionalidad de filtrado de datos, el resultado lucirá de la siguiente manera:

TablaFiltada1
Una tabla responsiva y filtrable por nombre de lenguaje de programación

La tabla contendrá una lista de desarrolladores. Cada fila mostrará un nombre, edad y lenguaje de programación. Cuando un usuario escriba en el campo de entrada de texto de la tabla, la tabla mostrará una lista filtrando las filas que estén relacionadas con el valor ingresado en el campo de entrada.

Durante el proceso de construcción de este proyecto, aprenderás sobre las propiedades CSS, así como el acceso y manipulación del DOM con JavaScript.

Puedes acceder al código de ejemplo en español desde CodeSandbox o del artículo original desde CodePen.

Primeros pasos

Necesitarás crear 3 archivos en tu carpeta del proyecto. Estos son index.html para el marcado, styles.css para los estilos, e index.js para el script.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Tabla Filtrable</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  
  <script src="index.js" type="text/javascript"></script>
</body>
</html>

Asegúrate de enlazar tus archivos de hoja de estilos y archivos de JavaScript al documento HTML tal y como se ha mostrado en el código anterior.

Marcado HTML para la tabla

Agregar el siguiente marcado al interior de las etiquetas body:

<div class="app">
    <input type="text" id="searchInput" placeholder="Filtrar por desarrollador..." />
    <table>
        <thead>
          <tr>
            <th>Nombre</th>
            <th>Edad</th>
            <th>Lenguaje</th>
          </tr>
        </thead>
        <tbody id="names">
          <tr>
            <td>Rey</td>
            <td>32</td>
            <td>JavaScript</td>
          </tr>
          <tr>
            <td>Samuel</td>
            <td>22</td>
            <td>Python</td>
          </tr>
          <tr>
            <td>Alegra</td>
            <td>28</td>
            <td>Ruby</td>
          </tr>
          <tr>
            <td>Juan</td>
            <td>29</td>
            <td>Python</td>
          </tr>
          <tr>
            <td>Daniel</td>
            <td>40</td>
            <td>JavaScript</td>
          </tr>
          <tr>
            <td>Maria</td>
            <td>21</td>
            <td>C</td>
          </tr>
          <tr>
            <td>David</td>
            <td>26</td>
            <td>JavaScript</td>
          </tr>
          <tr>
            <td>Krely</td>
            <td>31</td>
            <td>React</td>
          </tr>
          <tr>
            <td>Cleo</td>
            <td>43</td>
            <td>Java</td>
          </tr>
          <tr>
            <td>Pedro</td>
            <td>19</td>
            <td>Vue</td>
          </tr>
          <tr>
            <td>Jorge</td>
            <td>59</td>
            <td>Cobol</td>
          </tr>
          <tr>
            <td>Juanes</td>
            <td>29</td>
            <td>JavaScript</td>
          </tr>
          <tr>
            <td>Ernesto</td>
            <td>22</td>
            <td>PHP</td>
          </tr>
          <tr>
            <td>Sandra</td>
            <td>29</td>
            <td>R</td>
          </tr>
          <tr>
            <td>Verison</td>
            <td>34</td>
            <td>React Native</td>
          </tr>
          <tr>
            <td>Marta</td>
            <td>30</td>
            <td>React</td>
          </tr>
       </tbody>
    </table>
</div>

El primer elemento que encontraremos en el código es un campo de entrada de texto, usaremos este campo para recibir los datos del usuario.

Seguido de eso tenemos la tabla. La tabla consiste en una cabeza (thead) y un cuerpo (tbody). La cabeza de la tabla tiene una sola fila (tr) de datos, estos datos formarán el encabezado de la tabla. El cuerpo de la tabla está compuesto por 16 filas de datos, cada una de ellas contiene los siguientes campos: nombre, edad y lenguaje de programación.

Tanto el campo de texto como la tabla están envueltas en una etiqueta div. Esta organización ayudará con la alineación de los elementos mediante una hoja de estilos que veremos más adelante.

Salva los archivos y abre la página en un navegador, deberás ver el siguiente resultado:

image
Tabla HTML

Como estilizar la Tabla con CSS

Ahora es momento de aplicar algunos estilos a la tabla. Primeramente, estableceremos los estilos base de la siguiente manera:

@import url("https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap");

/* Se retira el margen y el padding al rededor del body. Se establece la altura del body al mismo tamaño del alto de la pantalla. Se alinea todo al centro, tanto en el eje horizontal como en el eje vertical*/

body {
  margin: 0;
  height: 100vh;
  padding: 0;
  font-family: "lato", sans-seriff;
  display: grid;
  justify-content: center;
  align-items: center;
  font-size: 20px;
}

/* Se remueven los bordes del input. Se establece un ancho igual que el elemento padre y se establece un margen en la parte inferior */

#searchInput {
  border: none;
  outline: none;
  width: 100%;
  margin-bottom: 20px;
}

/* Cuando el input gane el foco, se agregará un borde azul en la parte inferior */

#searchInput:focus {
  border-bottom: 2px solid #4575b6;
}

Como se ve a continuación la tabla se alineará al centro.

image-5

Para hacer que la tabla luzca aún mejor, agregaremos los siguientes estilos:

/* Establece el ancho del contenedor de la tabla (div) en un 80% del ancho de la ventana del navegador y el alto a un 100% del alto de la ventana del navegador. `vh` y `vw` hace responsiva a la table debido a que la escala proporcionalmente al tamaño de la ventana del navegador. Además, establece un margen de 20px en la parte superior y en la parte inferior */
.app {
  width: 80vw;
  height: 100vh;
  margin: 20px 0;
}

/* Colapsa todos los bordes que separan a cada celda. La tabla ocupa todo el ancho de ".app", además se establece una sobra gris alrededor de la tabla */
table {
  border-collapse: collapse;
  width: 100%;
  box-shadow: 0 5px 7px gray;
}

/* Establece una sombra en la cabeza de la tabla */
thead {
  box-shadow: 0px 0px 10px gray;
}

/* Agrega algo de espacio al rededor del encabezado de la tabla. Alinea el texto a la dereche y lo convierte a mayúsculas */

th {
  padding: 1rem 3rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  text-align: left;
}

/* Agrega un padding en cada celda */
td {
  padding: 0.5rem 3rem;
  font-size: 1rem;
}

/* Crea una alternancia de colores a lo largo de las filas de la tabla. Establece en color azul todas las filas pares (2, 4, 6 ...) */

tr:nth-child(even) {
  background-color: #dee8f5;
}

Ahora nuestra tabla luce mucho mejor y es responsiva también.

ResponsiveForm
La tabla ahora es responsiva

Como implementar la funcionalidad de filtrado con JavaScript.

La tabla de datos hasta este punto es meramente estática. Utilizando JavaScript, implementaremos la lógica para el filtrado de nombres en función de lo que el usuario escriba en la entrada de texto.

En tu archivo de script define una función llamada filtro. En las primeras tres líneas accederemos al valor de la entrada de texto del usuario, posterior a ello obtendremos la referencia del <tbody> y la guardaremos en la variable nombres, finalmente accederemos al contenido de todas las filas de la tabla <tr> usando el contenido en<tbody> mismo que está referenciado en la variable nombres.

Un aspecto importante para tener en cuenta es normalizar la entrada del usuario, para ello se aplicará una transformación a mayúsculas toda entrada que proporcione el usuario en la caja de texto (Si el usuario ingresa 'j' esta será transformada a 'J')

 /* Esta función recolectará la entrada del usuario
y tomando en cuenta dicha entrada mostrará u ocultará información 
de una fila en particular */

function filtro() {
    
  // Accede al texto de entrada y a varios elementos del DOM
  let valor = document.getElementById("searchInput").value.toUpperCase();
  let nombres = document.getElementById("names");
  let filas = nombres.getElementsByTagName("tr");

  // continua el código

El siguiente paso es iterar a través del arreglo de filas. Por cada fila accederemos a la última columna (columna del lenguaje de programación) y obtendremos el texto que contiene (valor actual).

for (i = 0; i < rows.length; i++) {
    let column = rows[i].getElementsByTagName("td")[2];
    let language = column.textContent;

    rows[i].style.display =
      language.toUpperCase().indexOf(value) > -1 ? "" : "none";
  }
}

document.getElementById("searchInput").addEventListener("keyup", filter);
Looping through the table rows

Si el contenido de la tabla en algunas de sus filas contiene cualquiera de los valores introducidos por el usuario desde la entrada de texto, las filas se mostrarán, en caso contrario se ocultarán. Para realizar esta operación usamos el operador ternario de asignación como una versión más corta de la sentencia condicional if.

Finalmente, agregamos un escuchador de eventos en la entrada, de modo que cada vez que una tecla es presionada, la función de filtrado será invocada.

A continuación, se presenta el código completo del script.

/* Esta función recolectará la entrada del usuario
y tomando en cuenta dicha entrada mostrará u ocultará información 
de una fila en particular */
function filtro() {
  // Accede al texto de entrada y a varios elementos del DOM
  let valor = document.getElementById("searchInput").value.toUpperCase();
  let nombres = document.getElementById("names");
  let filas = nombres.getElementsByTagName("tr");

  // Iteramos el arreglo de filas
  for(let i = 0; i < filas.length; i++){
    // Por cada fila se obtiene la referencia a la columna lenguaje
    let columnaLenguaje = filas[i].getElementsByTagName("td")[2];
    // Se extrae el texto de la columna lenguaje
    let lenguaje = columnaLenguaje.textContent;
    // Se muestra u oculta la fila si la entrada de texto
    // coincide con el texto de la columna lenguaje
    filas[i].style.display = lenguaje.toUpperCase().indexOf(valor) > -1 ? "" : "none";
  }
}

// Se agrega un escuchador de eventos a la entrada de texto
// para activar la función de filtrado cada vez que el usuario
// ingresa texto en la entrada
document.getElementById("searchInput").addEventListener("keyup", filtro);

La tabla final deberá lucir de la siguiente manera:

TablaFinal-1
Vista final del formulario

En conclusión

Con tan solo HTML, CSS y JavaScript puedes crear elementos realmente elegantes con funciones avanzadas.

Espero que hayas aprendido un par de cosas con este ejercicio. Una vez más, puedes revisar el código aquí y modificarlo a tu gusto.

Gracias por llegar hasta aqui conmigo.