I am trying to make my search bar hide all of the elements until the user actually searches for them.`Heres a JSfiddel
<div id="search">
<form>
<input type="text" name="search" id="myInput" onkeyup="mFunction()"
placeholder="Search ?..">
</form>
<nav>
<table id="myTable">
<tr class="header">
<th style="width:500px;">Question</th>
</tr>
<tr>
<td onclick="window.location.href='#web'">What is the company email?</td>
</tr>
<tr>
<td onclick="window.location.href='#web'">Is the website currently under
development?</td>
</tr>
<tr>
<td onclick="window.location.href='#game'">Why are the games not working
online?</td>
</tr>
<tr>
<td onclick="window.location.href='#game'">What is the next game or games
that you are working on?</td>
</tr>
<tr>
<td onclick="window.location.href='#game'">Are you working on Modern Jewels
anymore?</td>
</tr>
<tr>
<td onclick="window.location.href='#game'">What are the controls for Modern
Jewels?</td>
</tr>
</table>
</div>
</nav>`
JavaScript/jQuery
function mFunction() {
// Declare variables
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";
}
}
}
}
Do you know how, it is for a FAQ page and I want the users to be able to search for the questions without a load of questions all in the search.
Thanks any help appreciated :D
Since you have all the search results in the table, you can just toogle with the entire table by using jquerys .hide() and .show() animations.
to hide the table until user searches hide the table by using .hide()
$("#myTable").hide();
you could done this, by checking on keyup in your search. if the value is empty, then you can hide all of your table, else, you can show td in table which contains your search
$('table').hide();
$('#myInput').on("keyup", function(){
var searchVal = $('#myInput').val();
if(searchVal == ""){
$('table').hide();
}
else{
$('table').show();
$('table tr td').show();
$('table tr td:not(:contains("' + searchVal + '"))').hide();
}
});
demo : https://jsfiddle.net/p90uwdg7/
but this search is case sensitive, if you want to overcome this case sensitive, you need to overwrite the contains function
jQuery.expr[':'].contains = function(a, index, obj) {
return jQuery(a).text().toUpperCase()
.indexOf(obj[3].toUpperCase()) >= 0;
};
demo : https://jsfiddle.net/p90uwdg7/1/
Related
for some reason, every time i try to search or type in a text like Area15/Uptown or something, it doesn't remove the unrelated ones, did i do something wrong here?
I was trying to make a filter or something, to filter out what's on the table but it doesn't seem to work can anyone help or advice me on what i did wrong? am i lacking something here in my js?
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="search for places." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%">Town</th>
<th style="width:40%">Area</th>
</tr>
<tr>
<td>Downtown</td>
<td>Area15</td>
</tr>
<tr>
<td>Uptown</td>
<td>Area16</td>
</tr>
</table>
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementByTagName("tr");
for (i=0; i<tr.length; i++){
td= tr[i].getElementByTagName("td")[0];
if (td){
if (td.innerHTML.toUpperCase().indexof(filter) >-1) {
tr[i].style.display = " ";
} else {
tr[i}.style.display = "none";}
}
}
}
</script>
It is because of this line td= tr[i].getElementsByTagName("td")[0];It is searching only the first td inside tr.getElementsByTagName returns a collection & getElementsByTagName("td")[0] is asking to search only in the first td, If you chabge it to getElementsByTagName("td")[1] it will search only in second column
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");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[1];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<input id='myInput' onkeyup="myFunction()">
<table id="myTable">
<tr class="header">
<th style="width:60%">Town</th>
<th style="width:40%">Area</th>
</tr>
<tr>
<td>Downtown</td>
<td>Area15</td>
</tr>
<tr>
<td>Downtown</td>
<td>Area16</td>
</tr>
</table>
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();
}
I have a table that should eventually have 5 columns which I want to be able to sort though only the value of one column, "Name". This is what my function looks like so far:
function RenderResultsByName() {
//Declaration of variables
var nameInput, nameFilter, ul, li, a, i;
//Set the variables accorging to matching id's
//Name
nameInput = document.getElementById('nameInput');
nameFilter = nameInput.value.toUpperCase();
ul = document.getElementById("UL");
li = document.getElementsByTagName('tr');
console.log(li[0]);
//Loop trough items and hide those who don't match the query-->
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("td")[0];
if (a.innerHTML.toUpperCase().indexOf(nameFilter) > -1) {
li[i].style.display = "";
}
else {
li[i].style.display = "none";
}
}
}
The HTML looks like this
<div class="row">
<div class="col-md-3">
<label>Namn: </label><br />
<input type="text" id="nameInput" onkeyup="RenderResultsByName()" placeholder="Sök efter namn..." /> <br /> <br />
</div>
</div>
<br /><br />
<table id="UL" class="table table-bordered">
<tr>
<th>Name</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.visitor.FullName</td>
</tr>
}
</table>
I tried to apply a class "tdOfName" on all the 's in the Name column, but after that the sort stopped working because the a variable became undefined.
How would you solve this?
First, two things for your HTML code:
First a piece of advice, add thead and tbody to your tables to simplify jquery row selectors (and is a good practice, anyway).
You're creating 5 columns in the head row but only one in the rest. You have to add the rest or set a colspan.
<table id="UL" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
<th>Yada</th>
</tr>
<thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>#item.visitor.FullName</td><td></td><td></td><td></td><td></td>
</tr>
}
<tbody>
</table>
Then, you say sort but your function is trying to show/hide rows attending at the input of the value. I can't see any sign of sorting. In case what you want is show/hide rows that has the input value in the first column, you can simplify it with this...
jQuery.expr[':'].icontains = function(a, i, m) {
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};
$('input#nameInput').on('keyup',function() {
$('table#UL tbody tr').hide().filter(':has(td:first:icontains('+this.value+'))').show();
});
Here you have an fiddle example... https://fiddle.jshell.net/rigobauer/4rzf4wt7/
Is this what you're looking for?
I hope it helps.
I am using PHP and MySQL to build an HTML table. I am trying to use JavaScript to filter/search the table and only display the rows with the results I need. I want the JavaScript input to search multiple <td>s of the table. I was able to get this to work, but it is not going to be an elegant solution to put in place with larger tables.
I am sure there is a better way to choose what is being searched, but have not been able to find anything. Does anybody know a way for me to make this code more flexible for varying column width tables?
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");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
td1 = tr[i].getElementsByTagName("td")[1];
if (td+td1) {
if ((td.innerHTML.toUpperCase().indexOf(filter)+td1.innerHTML.toUpperCase().indexOf(filter)) > -2) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search" title="Type in anything">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Country</th>
</tr>
<tr>
<td>North/South</td>
<td>UK</td>
</tr>
<tr>
<td>Paris specialites</td>
<td>France</td>
</tr>
</table>
There's a lot you can improve. Start by remembering to explicitly declare your variables, otherwise they become global.
This solution doesn't rely on any specific number of columns. It will work no matter how many there are.
See comments inline for more:
// Get DOM references just once:
var input = document.getElementById("myInput");
var table = document.getElementById("myTable");
// Do event binding in JavaScript, not HTML
input.addEventListener("keyup", filter);
input.addEventListener("search", filter);
// Get all rows, except the header and convert to array so .forEach() can be used to loop
var rows = Array.prototype.slice.call(table.querySelectorAll("tr:not(.header)"));
function filter() {
// Always trim user input
var filter = input.value.trim().toUpperCase();
// Loop the rows
rows.forEach(function(row) {
// You really don't need to know if the search criteria
// is in the first or second cell. You only need to know
// if it is in the row.
var data = "";
// Loop over all the cells in the current row and concatenate their text
Array.prototype.slice.call(row.getElementsByTagName("td")).forEach(function(r){
// Don't use .innerHTML unless there is HTML. Use textContent when there isn't.
data += r.textContent;
});
// Check the string for a match and show/hide row as needed
// Don't set individual styles. Add/remove classes instead
if(data.toUpperCase().indexOf(filter) > -1){
// show row
row.classList.remove("hidden");
} else {
// hide row
row.classList.add("hidden");
}
});
}
input[type=search]{
border-radius:10px;
outline:0;
padding:3px;
}
input[type=search]:focus{
box-shadow:0 0 4px blue;
}
.hidden { display:none; }
.leftHeader { width:60%; }
.rightHeader { width:40%; }
<!-- Use the actual "search" input type and don't do inline CSS or JavaScript -->
<input type="search" id="myInput" placeholder="Search" title="Type in anything">
<table id="myTable">
<tr class="header">
<th class="leftHeader">Name</th>
<th class="rightHeader">Country</th>
</tr>
<tr>
<td>North/South</td>
<td>UK</td>
</tr>
<tr>
<td>Paris specialites</td>
<td>France</td>
</tr>
</table>
All what you have to do is to get the td content and then match it with the search input.
function search(value) {
$('table tr').each(function () {
var content = $(this).find('td').text();
if (content.toUpperCase().includes(value.trim().toUpperCase())) {
$(this).show();
} else {
$(this).hide();
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<input type="search" placeholder="Search..." id="search_account" onkeyup="search(this.value)">
<table>
<tr>
<td>Cell1</td>
<td>Cell2</td>
<td>Cell3</td>
</tr>
<tr>
<td>Cell4</td>
<td>Cell5</td>
<td>Cell6</td>
</tr>
</table>
</body>
</html>
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>