Resultado deseado: datos de entrada de un archivo .csv en PHP. Tome los datos del archivo .csv y guárdelos en una matriz. Almacene la matriz en una tabla HTML usando PHP. Use un motor de búsqueda para filtrar las filas usando JavaScript.
Recibo el siguiente error en JavaScript: TypeError no capturado: no se puede leer la propiedad 'textContent' de null
<script> const searchInput = document.getElementById("search"); const rows = document.querySelectorAll("tbody tr"); //console.log(rows); searchInput.addEventListener("keyup", function (event) { //console.log(event); const q = event.target.value.toLowerCase(); rows.forEach(row => { //console.log(row); row.querySelector("td").textContent.toLowerCase().startsWith(q); ? (row.style.display = "table-row") : (row.style.display = "none"); } ); }); </script>Usando el archivo console.log, pude determinar que está leyendo y recorriendo cada fila de la tabla correctamente, pero no puede recorrer el 'td' para determinar si coincide con el texto en el motor de búsqueda.
El Array es un NodeList al consolar las filas si esa información es útil.
Feliz de subir más información si es necesario. ¡De forma anticipada, muchas gracias por su ayuda!
EDITAR Agregar HTML mínimo. La tabla contiene 15 filas, pero a los efectos de esto, solo se agregan algunas. Esta tabla se crea a partir de una matriz usando PHP.
EDITAR 2 Encabezados agregados a thead
<html> <head> </head> <body> <input type="text" name="search" id="search" placeholder="Search for services.."> <table> <thead> <tr> <th>Item #</th> <th>Name</th> <th>Type</th> <th>Make</th> <th>Model</th> <th>Brand</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>1</td><td>Cut & Blow Dry</td> <td>Service</td> <td></td> <td></td> <td>Hair by Cass</td> <td>Haircut and style after</td> </tr> </tbody> </table> </body> </html><th> s debe ir en <thead> no en <tbody>; ? x : y ."input" para tener en cuenta las cosas de copiar/pegar del mouse, etc. searchInput.addEventListener("input", function(evt) { const q = evt.currentTarget.value.toLowerCase(); rows.forEach(row => { const matches = row.querySelector("td").textContent.toLowerCase().startsWith(q); row.style.display = matches ? "table-row" : "none"; }); }); Pero tenga en cuenta que row.querySelector("td") solo obtendrá el primer TD seguido (no todos):
Aquí hay un ejemplo que le permitirá buscar en cualquier celda y usa una mejor solución para alternar usando Element.classList.toggle() (y .includes() en lugar de .startsWith() )
const EL_search = document.querySelector("#search"); const ELS_rows = document.querySelectorAll("tbody tr"); EL_search.addEventListener("input", function(evt) { const q = evt.currentTarget.value.toLowerCase(); ELS_rows.forEach(TR => { const TDS = TR.querySelectorAll("td"); const matches = [...TDS].some(TD =>TD.textContent.toLowerCase().includes(q)); TR.classList.toggle("none", !matches); }); }); .none { display: none; } <input type="text" id="search" autocomplete="off"> <table> <thead> <tr><th>Name</th><th>Surname</th></tr> </thead> <tbody> <tr><td>Ann</td><td>Doe</td></tr> <tr><td>Jon</td><td>Doe</td></tr> <tr><td>Jonas</td><td>Foe</td></tr> </tbody> </table>El error proviene de row.querySelector("td") porque está tratando de encontrar td en el elemento tr de los encabezados que solo contiene los elementos th .
La solución es simple, verifique si se encontró td antes de continuar:
const td = row.querySelector("td"); if (!td) return; td.textContent.toLowerCase().startsWith(q) ? (row.style.display = "table-row") : (row.style.display = "none"); Además, querySelector solo devolverá el primer elemento encontrado, si necesita encontrar todos los elementos, use querySelectorAll , que devolverá la lista de elementos, y luego use for loop para procesar todos los elementos en la lista.
const tds = row.querySelectorAll("td"); for(let i = 0; i < tds.length; i++) { tds[i].textContent.toLowerCase().startsWith(q) ? (row.style.display = "table-row") : (row.style.display = "none"); }