javascript JS不工作预期与嵌套表

s5a0g9ez  于 2023-03-21  发布在  Java
关注(0)|答案(1)|浏览(139)

在下面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>
mdfafbf1

mdfafbf11#

最后,我设法解决了这个问题。我改变了
const cells = rows[i].querySelectorAll('td ')

const cells = rows[i].querySelectorAll('td:not(.table-data table td)')
现在它运行良好。
问题是因为querySelectorAll('td')选择了行中的所有单元格,包括嵌套的表格单元格,而不仅仅是我试图过滤的列中的单元格。这意味着当我试图使用cells[columnIndex].textContent访问指定列索引中单元格的文本内容时,我实际上是在获取该行中所有单元格的文本内容,包括嵌套表中的单元格。现在修改的代码只选择当前行中不在嵌套表中的单元格。

相关问题