soy Kseso y esto EsCSS

Javascript con Furoya: filtrar filas por palabra clave contenida en sus celdas

Segunda parte y continuación del artículo de Furoya sobre cómo detectar, con javascript puro, si en el contenido de un elemento hay o no una palabra clave y en función de ello actuar.
En esta entrega se aplica para filtrar el contenido de una tabla ocultando o mostrando filas en función de que exista cierto dato en alguna de sus celdas.

Javascript con Furoya: filtrar filas por palabra clave contenida en sus celdas

✎ 0
COLABORACIÓN AUTOR INVITADO
filtrar filas por palabra clave contenida en sus celdas

En el artículo anterior probamos buscar una cadena de texto escrita en un prompt() dentro de un párrafo usando (de entre varios métodos posibles) indexOf. Pero todavía no pasaba de ser un ejemplo de laboratorio.

La parte más complicada es recorrer todos los párrafos que puedan tener el texto que buscamos. Habíamos visto que querySelector() encuentra elementos usando sintaxis de CSS, pero sirve para atributos con valor no repetido: si hay más, sólo ve el primero.

querySelectorAll()

En cambio querySelectorAll() sí recorre todo el documento y reúne en un Node List (similar a un Array) cualquier coincidencia que encuentra con el selector. Pero justamente lo hace "numerando", y para acceder a cada elemento hay que llamarlo por ese número secuenciado.

Hay varias formas de hacerlo (¿les dije que esto pasa seguido en javascript?) y vamos a ver la más simple.

Usemos un HTML básico, y para variar un poco, cambiamos los párrafos por items de lista.

<dl> <dd>alfa, bravo, charly, delta, eco</dd> <dd>bravo, charly, delta, eco, FOXTROT</dd> <dd>charly, delta, eco, foxtrot, golf</dd> <dd>delta, eco, foxtrot, golf, hotel</dd> </dl>

Aquí tenemos varios elementos data description con palabras escritas dentro. La idea es destacar los <dd> que contengan una palabra en particular, y para decirle al "buscador" cuál queremos, vamos a seguir usando el mensaje modal.

Al código html anterior añadimos un poco de Css para remarcar el <dd> encontrado y el script necesario para nuestro propósito:

<style type="text/css"> .color { background-color: yellow; } </style> <script type="text/javascript"> var miTextoABuscar = prompt("Escriba una palabra de la lista en el documento.", "delta"); /*alert(miTextoABuscar); */ /*CREO UNA VARIABLE CON UNA LISTA DE TODOS LOS dd*/ var misDDs = document.querySelectorAll("dl > dd"); /*CREO UN BUCLE for CON VARIABLE miNodo DENTRO*/ for(miNodo in misDDs) { /*RECORRO CADA NODO (CADA dd) EN misDDs*/ var miDdActual = misDDs[miNodo]; /*LOS IDENTIFICO UNO A UNO, Y LOS PONGO EN UNA VARIABLE*/ var miTextoDd = miDdActual.textContent; /*EXTRAIGO EL TEXTO CONTENIDO HACIA OTRA VARIABLE*/ var miTextoEncontrado = miTextoDd.indexOf(miTextoABuscar); /*CONFIRMO EL NÚMERO DE ÍNDICE*/ //alert(miTextoDD+ " " +miTextoEncontrado) /*SI miTextoEncontrado NO ES IGUAL A -1, AGREGO LA CLASE AL dd*/ if(miTextoEncontrado != -1){ miDdActual.classList.add("color"); } } </script>

El script en detalle:

Este escript es como el visto en el artículo anterior, pero organizado de otra manera. Vamos a detenernos un poco en las novedades:

document.querySelectorAll("dl > dd") crea una lista parecida a un array, que contiene todos las dd que hay en cada dl, ordenadas de la primera a la última. Es solamente un objeto, una referencia interna para el JS sobre dónde está cada uno para después trabajar sobre el nodo que le pidamos. Si queremos saber el total, será misDDs.length; si queremos acceder al cuarto para ver su contenido, será misDDs[3].innerHTML (recordemos que los elementos se numeran desde 0, así que el cuarto es el nodo 3).

Como aquí tenemos que recorrerlos todos para confirmar en cuáles está la palabra a buscar, aplicamos el ya conocido bucle for(), pero para variar otra vez, usamos la versión for...in. La ventaja está en que no necesitamos limitar el número de vueltas, porque el mismo loop prueba desde 0 con nuestra variable miNodo si existe ese elemento en la lista misDDs, y cuando no encuentra más, se detiene.

Pero en algunos casos (como éste) no es muy recomendado por los programadores, ya que para confirmar el límite del Node List tiene que "pasarse" de nodos; y si bien for...in no tira un error, al aplicarse en la última (y excedida) vuelta sobre cualquier operación (en nuestro caso, al querer ubicar el indexOf del inexistente nodo 5) sí va a mostrar ése error en la consola web para javascript. Pero como nadie la ve, nosotros no decimos nada.

Apliación práctica: filtrar datos de tabla

Abandonemos un poco los casos ideales, y veamos una herramienta que ya conocimos en algunos formularios. Será una versión simplificada de un filtro para tablas, donde ingresamos un texto, y el escript nos muestra las filas que lo contienen.

See the Pen My ideals flights. by Kseso (@Kseso) on CodePen.

Ver Demo a Full

Para empezar, tenemos reemplazado el prompt modal por un más ortodoxo input, y agregamos el ya visto datalist de HTML 5. Si se lo perdieron, hay un artículo publicado en este blog al respecto: Nuevos inputs HTML 5.

El CSS es puramente decorativo, excepto dos clases; una que oculta todo el contenido (por filas) con display:none y otra que lo muestra. Nos van a servir para aplicarlas a las filas que queramos dejar visibles, o no.

El javascript ya arranca con una diferencia fundamental : está en su sitio natural, dentro del head. Como hay que tipear una información en el documento antes de ejecutarlo, ya no es útil que se inicie al final de la carga del HTML. Ahora lo vamos a hacer desde un botón en el formulario, y para eso le agregamos un evento onclick="", que se dispara al hacer click en su elemento, y ejecuta lo que tenga después del signo '='. En este caso, le ponemos el nombre de la función que inventamos nosotros, y que bautizamos tablero().

Todo lo que escribamos entre las llaves de una función, se va a ejecutar cuando la invoquemos desde (por ejemplo) un evento, así que nuestro programa lo hacemos con esta estructura:

<head> <script> function miNombreDeFuncion(){ alert("Cualquier línea JS a ejecutar."); } </script> </head>

Y se queda ahí dentro hasta que la llamemos desde otra función o desde algún evento como onclick (si vamos a hacer click), onload (cuando se cargue el documento o la imagen), onscroll (al arrastrar la barra de desplazamiento), o cualquiera de las decenas que existen.

Lo demás usa la misma lógica que venimos estudiando en los últimos artículos, pero aplicada a otro contexto:

«Lleno un campo de formulario con una palabra, hago click en un botón que dispara una función javascript creada para el caso. Esta función captura el valor de texto que está en el campo del formulario y la guarda en una variable; luego guarda en otra variable una referencia a todas las filas de tabla que estén en tbody, en formato de Node List, para después ubicar uno a uno los nodos con un bucle for...in y en cada uno probar si aparece el texto que buscamos. Con un condicional if...else aplicamos a la fila que estamos probando en esa vuelta del bucle un valor de class "oculta" o "muestra", segun el indexOf haya devuelto un -1 o cualquier otro número, respectivamente. Así, en todas las tr donde no esté el texto se va a reemplazar (o reescribir) con la clase que le da un display:none y donde aparezca, la clase le dará un display:table-row y quedará visible.»

Una novedad en el ejemplo es el operador !=. Significa "no es igual a", como se habrán imaginado. Y unElemento.className = "unNombreDeClase" simplemente reemplaza el valor de la clase por lo que pongamos entre las comillas; en el caso de que no haya una clase, escribe el atributo en el elemento y lo llena. Es una diferencia con el ya usado unElemento.classList.add("unNombreDeClase"), que agrega otro valor al que ya tenga puesto.

Con esto se podría cerrar el tema de "búsqudas en documento", pero aún hay un detalle que ya habrán notado al hacer pruebas con el pen: sigue distinguiendo mayúsculas de minúsculas.
Hay algunas formas de salvar esa incomodidad, y justifican una tercera parte. Aunque más no fuere para mencionarlas.

Autoría

Furoya: Autor del artículo

Artículo original de Furoya.
La intención del autor con sus colaboraciones no es que los artículos sirvan para hacer un copy&paste de códigos sino que comprendas y aprendas la lógica y el cómo trabaja javaScript.
Y a partir de lo expuesto experimentes tú.
El autor del post y el editor del blog te animamos a que plantees tus dudas o reflexiones y que compartas tus realizaciones en base a lo expuesto en los comentarios. Recuerda que puedes incluir pens (ejemplos en Codepen.io) en ellos.