Табличный фильтр/поиск по двум столбцам

Я пытаюсь сделать эту функцию поиска/фильтра фильтрующей, просматривая данные в col0 или col1. То, что я пытаюсь изменить JS, чтобы посмотреть на td = tr[i].getElementsByTagName("td")[0]; и td = tr[i].getElementsByTagName("td")[1];, но не могу заставить его работать.

Код работает для поиска по имени (не по стране):

function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[0];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }       
  }
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th, #myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header, #myTable tr:hover {
  background-color: #f1f1f1;
}
<!DOCTYPE html>
<html>
<head>
<meta name = "viewport" content = "width=device-width, initial-scale=1">
</head>
<body>

<h2>My Customers</h2>

<input type = "text" id = "myInput" onkeyup = "myFunction()" placeholder = "Search for names.." title = "Type in a name">

<table id = "myTable">
  <tr class = "header">
    <th style = "width:60%;">Name</th>
    <th style = "width:40%;">Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbkop</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Italy</td>
  </tr>
  <tr>
    <td>North/South</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Paris specialites</td>
    <td>France</td>
  </tr>
</table>

</body>
</html>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
31
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно искать в обоих элементах td для каждой строки. В вашем коде вы выполняете поиск только в первом столбце, потому что для каждой строки вы учитываете td = tr[i].getElementsByTagName("td")[0];, который является столбцом «Имя». Вам также необходимо учитывать второй элемент td: td = tr[i].getElementsByTagName("td")[1];.

В следующем фрагменте я просто добавляю еще один цикл for внутри myFunction(). Это позволяет проверить столбец «Имя» (j = 0), как вы делаете сейчас, а затем столбец «Страна» (j = 1).

function myFunction() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    //for each row check both columns
    for (j = 0; j < 2; j++){
       td = tr[i].getElementsByTagName("td")[j];
       if (td) {
         txtValue = td.textContent || td.innerText;
         if (txtValue.toUpperCase().indexOf(filter) > -1) {
           tr[i].style.display = "";
         } else {
           tr[i].style.display = "none";
         }
       }  
    }
  }
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th, #myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header, #myTable tr:hover {
  background-color: #f1f1f1;
}
<!DOCTYPE html>
<html>
<head>
<meta name = "viewport" content = "width=device-width, initial-scale=1">
</head>
<body>

<h2>My Customers</h2>

<input type = "text" id = "myInput" onkeyup = "myFunction()" placeholder = "Search for names.." title = "Type in a name">

<table id = "myTable">
  <tr class = "header">
    <th style = "width:60%;">Name</th>
    <th style = "width:40%;">Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbkop</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Koniglich Essen</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Italy</td>
  </tr>
  <tr>
    <td>North/South</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Paris specialites</td>
    <td>France</td>
  </tr>
</table>

</body>
</html>

Не работает, когда я ищу по именам

Mads Sander Høgstrup 17.05.2022 11:30
Ответ принят как подходящий

Вы можете взять textContent обоих столбцов, а затем отобразить строки, в которых textContent содержит filterText.

Я также внес следующие изменения в ваш код:

  • Обернутый заголовок таблицы в <thead> и тело таблицы в <tbody>.
  • Используется Элемент.дети для перебора всех строк в таблице.
  • Использовали Элемент.firstElementChild и Element.lastElementChild для захвата первого и второго столбца для каждой строки.
  • Используется String.prototype.includes для проверки наличия искомого текста в столбцах.
  • Передал event функции.

let tbody = document.getElementById("table-body");

function myFunction(e) {
  const filterText = e.target.value.toUpperCase();
  Array.from(tbody.children).forEach((row) => {
    const name = row.firstElementChild.textContent.toUpperCase();
    const country = row.lastElementChild.textContent.toUpperCase();

    if (name.includes(filterText) || country.includes(filterText)) {
      row.style.display = "table-row";
    } else {
      row.style.display = "none";
    }
  })
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th,
#myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header,
#myTable tr:hover {
  background-color: #f1f1f1;
}
<h2>My Customers</h2>
<input type = "text" id = "myInput" onkeyup = "myFunction(event)" placeholder = "Search for names.." title = "Type in a name">

<table id = "myTable">
  <thead>
    <tr class = "header">
      <th style = "width:60%;">Name</th>
      <th style = "width:40%;">Country</th>
    </tr>
  </thead>
  <tbody id = "table-body">
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Berglunds snabbkop</td>
      <td>Sweden</td>
    </tr>
    <tr>
      <td>Island Trading</td>
      <td>UK</td>
    </tr>
    <tr>
      <td>Koniglich Essen</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Laughing Bacchus Winecellars</td>
      <td>Canada</td>
    </tr>
    <tr>
      <td>Magazzini Alimentari Riuniti</td>
      <td>Italy</td>
    </tr>
    <tr>
      <td>North/South</td>
      <td>UK</td>
    </tr>
    <tr>
      <td>Paris specialites</td>
      <td>France</td>
    </tr>
    <tbody>
</table>

Если имеется более двух столбцов и вы хотите применить фильтр на основе всех столбцов, вы можете использовать Array.prototype.some и проверить, содержит ли какой-либо из столбцов искомый текст.

let tbody = document.getElementById("table-body");

function myFunction(e) {
  const filterText = e.target.value.toUpperCase();
  Array.from(tbody.children).forEach((row) => {
    const showRow = Array.from(row.children).some(c => c.textContent.toUpperCase().includes(filterText))
    if (showRow) {
      row.style.display = "table-row";
    } else {
      row.style.display = "none";
    }
  })
}
* {
  box-sizing: border-box;
}

#myInput {
  background-image: url('/css/searchicon.png');
  background-position: 10px 10px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#myTable th,
#myTable td {
  text-align: left;
  padding: 12px;
}

#myTable tr {
  border-bottom: 1px solid #ddd;
}

#myTable tr.header,
#myTable tr:hover {
  background-color: #f1f1f1;
}
<h2>My Customers</h2>
<input type = "text" id = "myInput" onkeyup = "myFunction(event)" placeholder = "Search for names.." title = "Type in a name">

<table id = "myTable">
  <thead>
    <tr class = "header">
      <th style = "width:60%;">Name</th>
      <th style = "width:40%;">Country</th>
    </tr>
  </thead>
  <tbody id = "table-body">
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Berglunds snabbkop</td>
      <td>Sweden</td>
    </tr>
    <tr>
      <td>Island Trading</td>
      <td>UK</td>
    </tr>
    <tr>
      <td>Koniglich Essen</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Laughing Bacchus Winecellars</td>
      <td>Canada</td>
    </tr>
    <tr>
      <td>Magazzini Alimentari Riuniti</td>
      <td>Italy</td>
    </tr>
    <tr>
      <td>North/South</td>
      <td>UK</td>
    </tr>
    <tr>
      <td>Paris specialites</td>
      <td>France</td>
    </tr>
    <tbody>
</table>

Если бы я добавил третий столбец, что мне тогда ввести вместо lastElementChild, так как этот столбец (Country) теперь будет посередине? В какой-то момент мне может понадобиться третий столбец

Mads Sander Høgstrup 17.05.2022 11:31

Я обновил свой ответ, пожалуйста, проверьте. Если вы хотите специально проверить какой-либо столбец, например, 3-й, вы можете сделать это, захватив этот конкретный дочерний элемент, например: row.children[2].

SSM 17.05.2022 11:51

Круто работает отлично!

Mads Sander Høgstrup 17.05.2022 12:30

Другие вопросы по теме