I have a table that I'm manipulating through a static js file. I made a filter to show only the lines that contain the values typed in the input. For that, I add the 'hidden' class to those that don't contain the value typed in the input. However, when I go to inspect, only the first line is configured with the "hidden" class. How do I do it for all the other lines that don't contain the values typed in the input?
The code:
HTML:
<div >
<hr>
<form >
<input id="form-control" type="text" name="fitrar" placeholder="Buscar Registros"
autocomplete="off" autofocus />
<a href="{% url 'registros' %}" id="id_btnlimpar" >Limpar</a>
</form>
</hr>
<table >
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">CNPJ</th>
<th scope="col">CPF</th>
<th scope="col">Nome</th>
</tr>
</thead>
<tbody>
{% for registro in registros %}
<tr>
<td scope="row">{{ registro.id }}</td>
<td scope="row"><a href="#modal{{registro.id}}" data-toggle="modal">{{ registro.cnpj }}</a></td>
<td scope="row">{{ registro.cpf }}</td>
<td scope="row">{{ registro.nome }}</td>
</tr>
JS:
const inputSearchRegistros = document.querySelector('.form-search input')
const tableRegistros = document.querySelector('.table tbody tr')
inputSearchRegistros.addEventListener('input', event => {
const inputValue = event.target.value.trim()
Array.from(tableRegistros.children)
.filter(regs => !regs.textContent.includes(inputValue))
.forEach(regs => {
regs.classList.add('hidden')
})
})
Result:
<tr>
<td scope="row" >1</td>
<td scope="row" ><a href="#modal1" data-toggle="modal">31024483000198</a></td>
<td scope="row" >86520083534</td>
<td scope="row" >Adriana teste esteves</td>
</tr>
<tr>
<td scope="row">2</td>
<td scope="row"><a href="#modal2" data-toggle="modal">31024483000198</a></td>
<td scope="row">86520083534</td>
<td scope="row">Adriana teste esteves</td>
</tr>
They are the same values, but only the first line receives the hidden class
I would like all lines that do not have the values typed in the input to receive the hidden class.
CodePudding user response:
Two problems:
- You are using
document.querySelector
, which will only select the first row. You want to usedocument.querySelectorAll
- You are iterating over the table cells using
Array.from(tableRegistros.children)
.
// this only selects the first row
const tableRegistros = document.querySelector('.table tbody tr');
// this is a bunch of td elements
Array.from(tableRegistros.children)
Instead, you want to iterate over all of the rows, and then all of the cells in each row:
// use querySelectorAll to select all rows
const tableRegistros = document.querySelectorAll('.table tbody tr');
// Iterate each row
tableRegistros.forEach(row => {
// Then search all of the cells for the content
const containsText = Array.from(row.children).some(cell => cell.textContent.includes(inputValue));
if (!containsText) {
row.classList.add('hidden');
} else {
row.classList.remove('hidden');
}
});
CodePudding user response:
querySelector only returns the first element that matches the selector even if there is more than one match. You want to use querySelectorAll like this
const tableRegistros = document.querySelectorAll('.table tbody tr')
You'll then have to loop through the results like in ryan's answer or select the td elements and loop through those like this
const tableRegistros = document.querySelectorAll('.table tbody tr td')
inputSearchRegistros.addEventListener('input', event => {
const inputValue = event.target.value.trim()
Array.from(tableRegistros)
.filter(regs => !regs.textContent.includes(inputValue))
.forEach(regs => {
regs.classList.add('hidden')
})
})