在下面HTML中,我有JS脚本来应用过滤器(filterTable),过滤器适用于列“ID”,“发票编号”,“日期”,“姓名”,“电子邮件”,“电话号码”,“地址”和“项目”,但它不适用于“税”,“发票总额”和“记录者”。
但奇怪的是,如果我用普通数据而不是嵌套表填充列“Items”,那么filterTable也会对列“Tax”,“Invoice Total”和“Logged by”起作用。
简而言之,如果我从“项目”中删除嵌套表,那么(filterTable)对于列“税”,“发票总额”和“记录人”工作良好。
添加快照以供参考(此处过滤器适用于“ID”,“发票编号”,“日期”,“姓名”,“电子邮件”,“电话号码”,“地址”和“项目”,但不适用于列“税”,“发票总额”和“记录人”,相反,当我在“税”中搜索时,它在“项目”列中找到。但是如果我从“项目”中删除嵌套表columns然后表中的所有列都可以正常工作。
下面是表
中的一些示例行
function updateDate(input) {
if (!input) {
filterTable(2, '');
return;
}
const [year, month, day] = input.split('-');
const monthAbbreviations = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
const formattedDate = `${day}-${monthAbbreviations[Number(month) - 1]}-${year}`;
filterTable(2, formattedDate);
}
function filterTable(columnIndex, filterValue) {
const table = document.querySelector('table');
const rows = table.querySelectorAll('tbody tr');
for (let i = 0; i < rows.length; i++) {
const cells = rows[i].querySelectorAll('td');
if (cells.length > columnIndex) {
const cellValue = cells[columnIndex].textContent.toString().toLowerCase();
console.log('cellValue:', cellValue);
console.log('filterValue:', filterValue);
console.log('columnindex:', columnIndex);
if (cellValue.includes(filterValue.toString().toLowerCase())) {
rows[i].style.display = '';
} else {
rows[i].style.display = 'none';
}
}
}
}
<table class="table table-striped">
<thead>
<tr>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="ID" onkeyup="filterTable(0, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Invoice Number" onkeyup="filterTable(1, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="date" oninput="updateDate(this.value)"><span id="formatted-date"></span></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Name" onkeyup="filterTable(3, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Email" onkeyup="filterTable(4, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Phone number" onkeyup="filterTable(5, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Address" onkeyup="filterTable(6, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Items" onkeyup="filterTable(7, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Tax" onkeyup="filterTable(14, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Invoice Total" onkeyup="filterTable(9, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Logged by" onkeyup="filterTable(10, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;">Invoice</th>
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td style="border: 1px solid black; padding: 10px;">{{ row[0] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[1] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[2] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[3] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[4] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[5] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[6] }}</td>
<td style="border: 1px solid black; padding: 10px;">
<table class="table table-striped" style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<th style="border: 1px solid black; padding: 10px;">Description</th>
<th style="border: 1px solid black; padding: 10px;">Price</th>
<th style="border: 1px solid black; padding: 10px;">Qty</th>
<th style="border: 1px solid black; padding: 10px;">Final Price</th>
</tr>
</thead>
<tbody>
{% set items = js.loads(row[7]) %} {% for item in items %}
<tr>
<td style="border: 1px solid black; padding: 10px;">{{ item.description }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ item.price }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ item.qty }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ item.final_price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[8] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[9] }}</td>
<td style="border: 1px solid black; padding: 10px;">{{ row[10] }}</td>
<td style="border: 1px solid black; padding: 10px;"><a href="{{ url_for('download', id=row[0]) }}">Download</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
重现错误的示例代码
一个二个一个一个
下面的代码可以用来查看,如果表没有嵌套表没有错误
function filterTable(columnIndex, filterValue) {
const table = document.querySelector('table');
const rows = table.querySelectorAll('tbody tr');
for (let i = 0; i < rows.length; i++) {
const cells = rows[i].querySelectorAll('td');
if (cells.length > columnIndex) {
const cellValue = cells[columnIndex].textContent.toString().toLowerCase();
//console.log('cellValue:', cellValue);
//console.log('filterValue:', filterValue);
//console.log('columnindex:', columnIndex);
if (cellValue.includes(filterValue.toString().toLowerCase())) {
rows[i].style.display = '';
} else {
rows[i].style.display = 'none';
}
}
}
}
<table id="myTable">
<thead>
<tr>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Tax" onkeyup="filterTable(0, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Invoice Total" onkeyup="filterTable(1, this.value)"></th>
<th style="border: 1px solid black; padding: 10px;"><input type="text" placeholder="Logged by" onkeyup="filterTable(2, this.value)"></th>
</tr>
</thead>
<tbody>
<tr>
<td>10%</td>
<td>$100</td>
<td>John Doe</td>
</tr>
<tr>
<td>5%</td>
<td>$50</td>
<td>Jane Doe</td>
</tr>
<tr>
<td>15%</td>
<td>$200</td>
<td>Bob Smith</td>
</tr>
</tbody>
</table>
1条答案
按热度按时间mdfafbf11#
最后,我设法解决了这个问题。我改变了
const cells = rows[i].querySelectorAll('td ')
与
const cells = rows[i].querySelectorAll('td:not(.table-data table td)')
现在它运行良好。
问题是因为querySelectorAll('td')选择了行中的所有单元格,包括嵌套的表格单元格,而不仅仅是我试图过滤的列中的单元格。这意味着当我试图使用cells[columnIndex].textContent访问指定列索引中单元格的文本内容时,我实际上是在获取该行中所有单元格的文本内容,包括嵌套表中的单元格。现在修改的代码只选择当前行中不在嵌套表中的单元格。