How to search 2nd column of table instead of 1st column - javascript

I have added a search box to my Bootstrap table. So the first thing that was added was this input which works fine but the I need to search the Country names instead of Names.
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
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";
}
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<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>
</table>

td = tr[i].getElementsByTagName("td")[1];
I suggest you only search the tbody
Also use eventlistener
document.getElementById("myInput").addEventListener("keyup",function() {
// Declare variables
const filter = this.value.toUpperCase();
const trs = document.querySelectorAll("#myTable tbody tr");
// Loop through all table rows, and hide those who don't match the search query
trs.forEach(tr => {
const td = tr.cells[1];
txtValue = td.textContent.toUpperCase()
tr.hidden = txtValue && !txtValue.includes(filter)
})
});
<input type="text" id="myInput" placeholder="Search for names.." autocomplete="off">
<table id="myTable">
<thead>
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Germany</td>
</tr>
<tr>
<td>Microsoft</td>
<td>USA</td>
</tr>
</tbody>
</table>

Related

How can I only show the table when the filter is complete

I got a project in which in which i got some data in format of html table and asked to make a web page where you put in the phone number of a person and when you click the button you will get the result filtered out from the data. You will not be able to see someone's else data without knowing their phone number. I made it till here-
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
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";
}
}
}
}
</script>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search">
<table id="myTable">
<tr class="header">
<th>Phone</th>
<th>Name</th>
<th>DOB</th>
</tr>
<tr>
<td>1239832</td>
<td>Rhythm</td>
<td>Class 10</td>
</tr>
<tr>
<td>2198320</td>
<td>Rekha</td>
<td>Class 11</td>
</tr>
<tr>
<td>21397293</td>
<td>Arun</td>
<td>Class 11</td>
</tr>
</table>
Here is a much simplified version. You need to type or paste the complete number to see the information
Note that this is not safe if you want to hide the information from the user if they do not know the number because they can just look in the source code. If you need a safer lookup, you need to send the number to the server
const trs = document.querySelectorAll("#myTable tbody tr");
document.getElementById("myInput").addEventListener("input", function() {
const filter = this.value;
// Loop through all table rows, and hide those who don't match the search query
trs.forEach(tr => tr.hidden = filter && tr.querySelector("td").textContent !== filter)
})
</script>
<input type="text" id="myInput" placeholder="Search">
<table id="myTable">
<thead>
<tr class="header">
<th>Phone</th>
<th>Name</th>
<th>DOB</th>
</tr>
</thead>
<tbody>
<tr hidden>
<td>1239832</td>
<td>Rhythm</td>
<td>Class 10</td>
</tr>
<tr hidden>
<td>2198320</td>
<td>Rekha</td>
<td>Class 11</td>
</tr>
<tr hidden>
<td>21397293</td>
<td>Arun</td>
<td>Class 11</td>
</tr>
</tbody>
</table>

How to not display none when checkbox already checked in filter vanilla javascript?

I tried to make the checked tr, not to be displayed none when filtering the new input.
for example, when I tried to input a new value after checking the tr the tr will not disappear.
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 {
// if (tbody.querySelectorAll(".doms:checked")) {
// tblRows[i].style.display = "";
// } else {
let checks = tr[i].getElementsByTagName("td")[1];
let far = checks.getElementsByTagName("input");
tr[i].style.display = "none";
}
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">List Things</th>
<th style="width:40%;">Approved</th>
</tr>
<tr>
<td>Rock</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Rock2</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Car</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>House</td>
<td><input type="checkbox"></td>
</tr>
</table>
I don't know how to make it happen
There is minor change in your code. While you get your input you use let far = checks.getElementsByTagName("input"); which returns array, so you just need to add index with it as let far = checks.getElementsByTagName("input")[0] so it will select relative input. Then add condition if (far.checked) will work.
Also you do not need to get td from tr[i] then far object. Instead you can directly use let far = tr[i].getElementsByTagName("input")[0].
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 {
// below lines can be ommitted
// let checks = tr[i].getElementsByTagName("td")[1];
// use tr[i] below and get input element with index [0]
let far = tr[i].getElementsByTagName("input")[0];
// add below condition to hide tr only if checkbox is not checked
if (!far.checked) {
tr[i].style.display = "none";
}
}
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">List Things</th>
<th style="width:40%;">Approved</th>
</tr>
<tr>
<td>Rock</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Rock2</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Car</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>House</td>
<td><input type="checkbox"></td>
</tr>
</table>

Search in HTML Table the th tag

<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
I have the following table
<table class="table table-condensed table-bordered table-hover" id="myTable">
<tr>
<th>#Id</th>
<td>Channel:0</td>
</tr>
<tr>
<th>#Name</th>
<td>C1</td>
</tr>
<tr>
<th>BitCountRange</th>
<td>14</td>
</tr>
<tr>
<th>PixelType</th>
<td>Bgr48</td>
</tr>
<tr>
<th>DyeName</th>
<td>C1</td>
</tr>
<tr>
<th>ShortName</th>
<td>C1</td>
</tr>
<tr>
<th>ColorMode</th>
<td>None</td>
</tr>
</table>
I want to search the th tags with the following w3 javascript tryout script:
<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++) {
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";
}
}
}
}
</script>
This script is working fine if the search is based on the td tags. But I want to search the table header/columns (th).
I have tried following chances on this code:
td = tr[i].getElementsByTagName("th")[0];
td = tr[i].getElementsByTagName("th");
But both is not working. I have no experience in js, and this script is for a usage in flask.
You can get all the table headers using getElementsByTagName and specifying th as the tag.
<table class="table table-condensed table-bordered table-hover" id="myTable">
<tr>
<th>#Id</th>
<td>Channel:0</td>
</tr>
<tr>
<th>#Name</th>
<td>C1</td>
</tr>
<tr>
<th>BitCountRange</th>
<td>14</td>
</tr>
<tr>
<th>PixelType</th>
<td>Bgr48</td>
</tr>
<tr>
<th>DyeName</th>
<td>C1</td>
</tr>
<tr>
<th>ShortName</th>
<td>C1</td>
</tr>
<tr>
<th>ColorMode</th>
<td>None</td>
</tr>
</table>
<script>
//get all th's
var ths = document.getElementsByTagName("th");
for (let thisTh of ths) {
console.log(thisTh);
}
</script>
Debugging this code using f12 in your browser reveals each th object and the properties available, like the text in the tag header. Simply pass in the text you are searching for to the routine above and when you find the th with the matching text.
The object thisTh will have a parentNode, as the table row, and a sibling, which is the td wiith the value.
You need to replace tr = table.getElementsByTagName("th");
with tr = document.getElementsByTagName("th");
I have commented out the wrong code and used the correct code in the attached snippet.
<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");
tr = document.getElementsByTagName("th");
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";
}
}
}
}
</script>
You only need replace "td" with "th" in the JS code the input will filter by text in the <th> tags.
Please review the updated code.
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];
td = tr[i].getElementsByTagName("th")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table class="table table-condensed table-bordered table-hover" id="myTable">
<tr>
<th>#Id</th>
<td>Channel:0</td>
</tr>
<tr>
<th>#Name</th>
<td>C1</td>
</tr>
<tr>
<th>BitCountRange</th>
<td>14</td>
</tr>
<tr>
<th>PixelType</th>
<td>Bgr48</td>
</tr>
<tr>
<th>DyeName</th>
<td>C1</td>
</tr>
<tr>
<th>ShortName</th>
<td>C1</td>
</tr>
<tr>
<th>ColorMode</th>
<td>None</td>
</tr>
</table>

How to have a dropdown searchbox that filters table results?

I am still new to programming and currently I encounter a problem. I have used a code from W3schools which allows me to filters the table when it matches the search result. However, I want to make it better for the users of the website. I want to allow them to be able to search through the searchbox and also give them the option to select a dropdown from the box which returns the same result.
Below is the code I have used for HTML:
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.."><table id="myTable">
<tr class="header">
<th style="width:60%;">Fruit Name</th>
<th style="width:40%;">Place of Origin</th>
</tr>
<tr>
<td>Apple</td>
<td>Asia</td>
</tr>
<tr>
<td>Black Berry</td>
<td>North America</td>
</tr>
<tr>
<td>Durian</td>
<td>SouthEast Asia</td>
</tr>
<tr>
<td>Watermelon</td>
<td>South Korea</td>
</tr></table>
And the JavaScript used:
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
I'm sorry for this mess, in short, these were taken from the W3school site with some changes. Instead of having just a search box, I want to implement a drop down with the search box if it is possible. Any help would be greatly appreciated.
Based on your comments, below is the updated code with search box as well as dropdown that will filter rows:
function myFunction(searchTerm) {
var input, filter, table, tr, td, i;
filter = searchTerm.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
var options = $("#fruitOptions");
$("#myTable tr:not(.header)").each(function() {
options.append($("<option />").val($(this).find("td:first-child").text()).text($(this).find("td:first-child").text()));
});
$("#myInput").on('input', function() {
myFunction($(this).val());
});
$("#fruitOptions").on('change', function() {
myFunction($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="myInput" placeholder="Search for names..">
<select id="fruitOptions">
<option value=''>- Please select -</option></select>
<table id="myTable">
<tr class="header">
<th style="width:60%;">Fruit Name</th>
<th style="width:40%;">Place of Origin</th>
</tr>
<tr>
<td>Apple</td>
<td>Asia</td>
</tr>
<tr>
<td>Black Berry</td>
<td>North America</td>
</tr>
<tr>
<td>Durian</td>
<td>SouthEast Asia</td>
</tr>
<tr>
<td>Watermelon</td>
<td>South Korea</td>
</tr>
</table>
Try this :
HTML
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<select id="selectItems">
<option>NA</option>
</select>
<table id="myTable">
<tr class="header">
<th style="width:60%;">Fruit Name</th>
<th style="width:40%;">Place of Origin</th>
</tr>
<tr>
<td>Apple</td>
<td>Asia</td>
</tr>
<tr>
<td>Black Berry</td>
<td>North America</td>
</tr>
<tr>
<td>Durian</td>
<td>SouthEast Asia</td>
</tr>
<tr>
<td>Watermelon</td>
<td>South Korea</td>
</tr></table>
Javascript:
function init()
{
//insert item in dropdown from table.
var html_for_elect = '';
var itm_dd = document.getElementById("selectItems");
table1 = document.getElementById("myTable");
trtbl = table1.getElementsByTagName("tr");
for (i = 0; i < trtbl.length; i++) {
td = trtbl[i].getElementsByTagName("td")[0];
if (td) {
html_for_elect = html_for_elect + "<option>"+td.innerHTML+"</option>";
}
}
itm_dd.innerHTML = html_for_elect;
}
init();
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function myFunction1() {
var input, filter, table, tr, td, i;
input = document.getElementById("selectItems");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
document.getElementById("myInput").value= input.value;
}
// myFunction1 can be use as (only use one of these myFunction1 functions):
function myFunction1() {
document.getElementById("myInput").value=
document.getElementById("selectItems").value;
myFunction();
}

How can I hide a table until filtered/input entered in search

I'm new to web developing but catching on fairly quickly. I'm developing a wiki page for my company and I have a filter table built but I want to hide the table until the filter function is applied when a user enters their search text. So this way it only shows the text input box and then when they type in their search the table results will THEN show.
I'm using this Javascript for the filtering:
function ContactsearchFX() {
var input, filter, table, tr, td, i;
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) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
on a basic search table with this html code:
<input type="text" id="myInput" onkeyup="ContactsearchFX()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Number</th>
</tr>
<tr>
<td>contact</td>
<td>number</td>
</tr>
<tr>
<td>contact</td>
<td>number</td>
</tr>
<tr>
<td>contact</td>
<td>number</td>
</tr>
....and so on.
window.onload = function() {
var rows = document.querySelectorAll('tr:not(.header)');
for (var i = 0; i < rows.length; i++) {
rows[i].style.display = 'none';
}
}
function ContactsearchFX() {
var input, filter, table, tr, td, i;
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) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
var rows = document.querySelectorAll('tr:not(.header)');
if (input.value.length == 0) {
for (var i = 0; i < rows.length; i++) {
rows[i].style.display = 'none';
}
}
}
<input type="text" id="myInput" onkeyup="ContactsearchFX()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Number</th>
</tr>
<tr>
<td>test 1</td>
<td>number</td>
</tr>
<tr>
<td>test 2</td>
<td>number</td>
</tr>
<tr>
<td>test 3</td>
<td>number</td>
</tr>
This seems to do the trick! On the load of the window, it loops through all the table rows which do now have the class of header. So your header, is always visible.
Then as your code originally did, it goes through the table and filters out the ones that are matching.
After this, I just added in another loop which then sets the rows back to display: none if there is nothing that is in the input box.
Hope this is what you were looking for.
You could give the table default styles that hide it so when it renders, its default state will be hidden.
<input type="text" id="myInput" onkeyup="ContactsearchFX()" placeholder="Search for names..">
<table id="myTable" style="display:none;">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Number</th>
</tr>
<tr>
<td>contact</td>
<td>number</td>
</tr>
<tr>
<td>contact</td>
<td>number</td>
</tr>
<tr>
<td>contact</td>
<td>number</td>
</tr>
I would suggest running the ContactsearchFX function on page load:
document.addEventListener('DOMContentLoaded', ContactsearchFX);
... and requiring that filter is not the empty string in the condition for displaying a row.
This has one particular advantage: some browsers remember the last text that was entered in the input box, and fill that text automatically again on page load. With this solution, the corresponding table rows will be filtered immediately.
For a more responsive effect, I would remove the onkeyup="ContactsearchFX()" HTML attribute, and instead add the following JavaScript:
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('myInput').addEventListener('input', ContactsearchFX);
});
Also consider using the rows and cells collections instead of getElementsByTagName
Probably you want to keep the header row out of the filtering process, and so your loop should start at 1 instead of 0.
document.addEventListener('DOMContentLoaded', function () {
ContactsearchFX();
document.getElementById('myInput').addEventListener('input', ContactsearchFX);
});
function ContactsearchFX() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.rows;
for (i = 1; i < tr.length; i++) {
td = tr[i].cells[0];
if (td) {
tr[i].style.display = filter && td.textContent.toUpperCase().indexOf(filter) > -1
? "" : "none";
}
}
}
<input type="text" id="myInput" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Number</th>
</tr>
<tr>
<td>test 1</td>
<td>number</td>
</tr>
<tr>
<td>test 2</td>
<td>number</td>
</tr>
<tr>
<td>test 3</td>
<td>number</td>
</tr>
</table>

Categories