What is the best way to search all the columns in my HTML table? Currently, my table only searches the first column.
Additionally, my table has multiple header rows. I am not sure what is the best way to display search results if the results are only for certain header sections. Only the related headers should be displayed with the search results.
https://codepen.io/magic12/pen/QWmvGBX
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";
}
}
}
}
table.table_brdr td {
padding: 8px 10px;
border: none;
}
table.table_brdr th {
background-color: #a6a6a6;
color: black;
}
tr:nth-of-type(odd) {
background-color#D3D3D3;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 20%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
<p>
<input
type="text"
id="myInput"
onkeyup="myFunction()"
placeholder="Search"
title="Searche"
/>
</p>
<table id="myTable">
<tbody>
<tr>
<th>Column1</th>
<th><strong>Column2</strong></th>
<th>Column3</th>
</tr>
<tr>
<td>abc</td>
<td>xyz</td>
<td>03/30/2017</td>
</tr>
<tr>
<td>test12</td>
<td>https://www.yahoo.com/</td>
<td>03/30/2017</td>
</tr>
<tr>
<th>Column1</th>
<th>New Column</th>
<th>Column3</th>
</tr>
<tr>
<td>John</td>
<td>abctd</td>
<td>09/30/2019</td>
</tr>
<tr>
<th>Column1</th>
<th>New Column2</th>
<th>Column3</th>
</tr>
<tr>
<td>Doe</td>
<td>abctd</td>
<td>06/30/2019</td>
</tr>
</tbody>
</table>
CodePudding user response:
This is the culprit
td = tr[i].getElementsByTagName("td")[0];
Try this and let me know.
<script>
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 ) {
var allTDs = tr[i].getElementsByTagName("td");
for (index = 0; index < allTDs.length; index ) {
txtValue = allTDs[index].textContent || allTDs[index].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
break;
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
<p><input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search" title="Searche"></p>
<table id="myTable">
<tbody>
<tr>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
</tr>
<tr>
<td>abc</td>
<td>xyz</td>
<td>03/30/2017</td>
</tr>
<tr>
<td>test12</td>
<td>https://www.yahoo.com/ </td>
<td>03/30/2017</td>
</tr>
<tr>
<th>Column1</th>
<th>New Column</th>
<th>Column3</th>
</tr>
<tr>
<td>John</td>
<td>abc
<td>09/30/2019</td>
</tr>
<tr>
<th>Column1</th>
<th> New Column2</th>
<th>Column3</th>
</tr>
<tr>
<td>Doe</td>
<td>abctd </td>
<td>06/30/2019</td>
</tr>
</tbody>
</table>
CodePudding user response:
You could use tr.innerText
to get all the text content of that table row. Then do your usual comparison.
function myFunction() {
const input = document.getElementById("myInput");
const filter = input.value.toUpperCase();
const table = document.getElementById("myTable");
const tr = table.getElementsByTagName("tr");
for (let i = 0; i < tr.length; i ) {
const txtValue = tr[i].innerText.toUpperCase();
if (txtValue.indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
CodePudding user response:
Details are commented in the example
// Reference <form> and <table>
const form = document.forms.UI;
const table = document.querySelector("table");
// Bind <form> to the submit event
form.onsubmit = searchTable;
/*
Event handler passes Event Object by default
1. Stop the <form> from sending data to server
Reference all form controls
Get the string value from <input>
4. Split it up and re-join it into "xxx|xxx" pattern
Collect all <td> into an array
Declare some variables
8. Iterate through array of <td>
Store text of current <td>
If there is text in the current <td>...
... define a RegExp that matches the <input> value...
...then split the string into an array and then
replace matches with the same text with <mark>
tag wrapped around it
Finally render the string into HTML
*/
function searchTable(event) {
event.preventDefault(); // 1.
const IO = this.elements;
let terms = IO.search.value;
terns = terms.split(' ').join('|'); // 4.
const tCells = [...table.querySelectorAll('td')];
let text, rgx, match;
// 8.
tCells.forEach((td, idx) => {
text = td.textContent;
if (text.length > 0) {
rgx = new RegExp(`(${terms})`, 'gim');
match = text.split(' ').join(' ').replace(rgx, `<mark>$1</mark>`);
}
td.innerHTML = match;
});
}
*,
*::before,
*::after {
margin: 0;
box-sizing: border-box
}
html {
font: 300 2ch/1.2 'Segoe UI';
}
fieldset {
display: flex;
width: max-content;
margin: 20px auto;
}
button,
input {
display: inline-flex;
justify-content: center;
align-items: center;
width: max-content;
height: 2rem;
padding: 4px 8px;
font: inherit;
}
button:hover {
cursor: pointer;
}
#search {
width: 75%;
margin-bottom: 12px;
border: 1px solid #ddd;
}
td {
padding: 8px 10px;
border: none;
}
th {
padding: 8px 10px;
background-color: #a6a6a6;
color: #930;
}
tr:nth-of-type(odd) {
background-color: #D3D3D3;
}
mark {
font-weight: 900;
color: red;
}
<form id='UI'>
<fieldset>
<input id="search" name="search" placeholder="Enter search terms here..." title="Search Table" type="search">
<button>Search