How can I hide search results until I've entered text? - javascript

Basically, this code makes it so that all results show and get trimmed down when you search for something specific. I want to hide all results before I've started writing and when I've entered at least one letter results show up again. I've been stuck at that exact problem for hours and have concluded with nothing.
I'd really appreciate the help.
function Function() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById('Input');
filter = input.value.toUpperCase();
ul = document.getElementById("UL");
li = ul.getElementsByTagName('li');
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
#Input {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 30%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
justify-content: center;
height: 20px;
}
#media screen and (max-width: 600px) {
#Input {
width: 80%;
margin-top: 4px;
}
}
;
#UL {
list-style-type: none;
padding: 0;
margin: 0;
}
#UL li a {
border: 1px solid #ddd;
margin-top: -1px;
background-color: #f6f6f6;
padding: 12px;
width: 30%;
text-decoration: none;
font-size: 18px;
color: black;
display: block;
}
#UL li a:hover:not(.header) {
background-color: #eee;
}
<input type="text" id="Input" onkeyup="Function()" placeholder="Search...">
<ul id="UL" style="list-style: none;">
<li class="listClass">SONY a6000</li>
<li class="listClass">SONY a6400</li>
<li class="listClass">SONY a7 IV</li>
<li class="listClass">Canon EOS RP</li>
<li class="listClass">Nikon D3500</li>
<li class="listClass">Hasselblad X1D II 50C</li>
</ul>

Given your html structure you can do this in one line of css:
#Input:focus:placeholder-shown + ul {
display:none;
}
It works because you have placeholder text on your input element, and the <ul> is adjacent to it. Read more here:
https://developer.mozilla.org/en-US/docs/Web/CSS/:placeholder-shown
https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator

If I understand correctly, Initially all the results will be shown? Then when you start typing they will be hidden(not entered any letter) and after entering atleast one element they start showing again? In that case you can use onfocus event along with onkeyup event.
function Function() {
let input, filter, ul, li, a, i, txtValue;
input = document.getElementById('Input');
filter = input.value.toUpperCase();
ul = document.getElementById("UL");
li = ul.getElementsByTagName('li');
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1 && filter!=='') {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
#Input {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 30%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
justify-content: center;
height: 20px;
}
#media screen and (max-width: 600px) {
#Input {
width: 80%;
margin-top: 4px;
}
}
;
#UL {
list-style-type: none;
padding: 0;
margin: 0;
}
#UL li a {
border: 1px solid #ddd;
margin-top: -1px;
background-color: #f6f6f6;
padding: 12px;
width: 30%;
text-decoration: none;
font-size: 18px;
color: black;
display: block;
}
#UL li a:hover:not(.header) {
background-color: #eee;
}
<input type="text" id="Input" onkeyup="Function()" onfocus="Function()" placeholder="Search...">
<ul id="UL" style="list-style: none;">
<li class="listClass">SONY a6000</li>
<li class="listClass">SONY a6400</li>
<li class="listClass">SONY a7 IV</li>
<li class="listClass">Canon EOS RP</li>
<li class="listClass">Nikon D3500</li>
<li class="listClass">Hasselblad X1D II 50C</li>
</ul>
If you want to show all the results again when unfocusing the input field (and not any letter in the input field) then you can use onblur event to achieve that as well by modifying input field like below and add the function.
function Function2()
{
let input, filter, ul, li, a, i, txtValue;
input = document.getElementById('Input');
filter = input.value.toUpperCase();
ul = document.getElementById("UL");
li = ul.getElementsByTagName('li');
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
<input type="text" id="Input" onkeyup="Function()" onfocus="Function()" onblur="Function2()" placeholder="Search...">

Related

Searchable drop down

I have a list of items in a drop down which is filterable using a search within the dropdown.
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Please select</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
Abyssinian
American Bobtail
Amercian Curl
</div>
</div>
And the js...
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
txtValue = a[i].textContent || a[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
}
https://codepen.io/RSA_James/pen/LYZqYym
What I'm after is a way of showing a message if a user starts searching for something and there's no matches.
Any help appreciated! Thanks
ES6 shrinks the code a bit:
function filterFunction(sText) {
[...document.querySelectorAll('#myDropdown a')].forEach(elA => elA.classList.toggle('hide', !new RegExp(sText, 'gi').test(elA.textContent)));
document.querySelector('#myDropdown span.err').classList.toggle('hide', document.querySelectorAll('#myDropdown a:not(.hide)').length);
}
.hide { display: none; } .err { color: red; }
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Please select</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" oninput="filterFunction(this.value)">
Abyssinian
American Bobtail
Amercian Curl
<span class="err hide">Nothing found</span>
</div>
</div>
Have a look here, added some new code and created a new element when there is no found result.
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
var empty = document.createElement("a");
empty.classList.add("empty");
empty.innerHTML="No Reault Found...";
var emptyVisiable= true;
for (i = 0; i < a.length; i++) {
txtValue = a[i].textContent || a[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
emptyVisiable = false;
} else {
a[i].style.display = "none";
}
}
if (emptyVisiable)
div.appendChild(empty);
else {
empty= div.querySelector(".empty")
if (empty!== null)
empty.remove();
}
}
.dropbtn {
background-color: #e3e3e3;
background-image: url('https://image.flaticon.com/icons/png/512/25/25243.png');
background-position: 270px center;
background-repeat: no-repeat;
background-size: 5%;
color: #333 ;
border: 1px solid red;
border-radius: 5px;
min-width: 300px;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
text-align: left;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #d3d3d3;
}
#myInput {
box-sizing: border-box;
background-image: url('https://www.w3schools.com/howto/searchicon.png');
background-position: 14px 12px;
background-repeat: no-repeat;
font-size: 16px;
padding: 14px 20px 12px 45px;
border: none;
border-bottom: 1px solid #ddd;
width: 100%;
}
#myInput:focus {outline: 3px solid #ddd;}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f6f6f6;
min-width: 230px;
width: 100%;
max-height: 260px;
overflow: auto;
border: 1px solid #ddd;
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
<h2>Search/Filter Dropdown</h2>
<p>Click on the button to open the dropdown menu, and use the input field to search for a specific dropdown link.</p>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Please select</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
Abyssinian
American Bobtail
Amercian Curl
American Longhair
American Shorthair
American Wirehair
Angora
Asian
Asian Blue
Balinese
Bengal
Bengal Tiger
Bicolour
Bicolour Longhair
British Bicolour Shorthair
Birman
Black
Black and White
Black and White Longhair
Black and White Shorthair
Black Longhair
Black Shorthair British Black
</div>
</div>
you can accomplish this by adding a p tag for the error in the html and a counter that increments each time no res is found in the loop of your filter function followed by an if at the end that checks to see if the counter === the lengths of links
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
let count = 0;
for (i = 0; i < a.length; i++) {
txtValue = a[i].textContent || a[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
count++;
a[i].style.display = "none";
}
}
if(count == a.length )
displayNoResults(filter);
}
function displayNoResults(searchTxt) {
let noResFound = document.getElementById("noResFound");
noResFound.style.display = "block"
noResFound.innerHTML = `No results for "${searchTxt}" were found`
}
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Please select</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
<p id="noResFound"></p>
Abyssinian
American Bobtail
Amercian Curl
</div>
</div>

Search bar is only searching on first p tag

I am trying to implement a search bar into my webb application using .net core MVC.
I have found some code online but the problem is it will only search depending on the first p-tag.
Can't quite figure it out how to make it search through all p-tags before setting the display to none.
This is my JS function:
function myFunction() {
var input, filter, ul, li, p, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
p = li[i].getElementsByTagName("p")[0];
txtValue = p.textContent || p.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
This is my cshtml:
<ul id="myUL" style="display: inline;
list-style: none;">
#await foreach (var logopedist in Model)
{
<li class="lijst" style="margin-top: 10px;
padding-left: 10px;
background-color: #1d71b8;
color: #ffffff;
font-size: 10pt;
padding-right: 10px;
padding-bottom: 5px;
padding-top: 5px;">
<p style="font-size:14px; font-weight:bold;">#logopedist.Naam, #logopedist.PraktijkNaam</p>
<p>#logopedist.Adres</p>
<p>#logopedist.Email</p>
<p>#logopedist.Mobiel</p>
</li>
}
I suggest this version
window.addEventListener("load", function() {
document.getElementById("myInput").addEventListener("input", function() {
const filter = this.value.toUpperCase();
[...document.querySelectorAll("#myUL li")].forEach(li => {
const txtValue = (li.textContent || li.innerText).toUpperCase();
li.classList.toggle("hide",txtValue.indexOf(filter) === -1)
});
})
})
#myUL {
display: inline;
list-style: none;
}
#myUL li {
margin-top: 10px;
padding-left: 10px;
background-color: #1d71b8;
color: #ffffff;
font-size: 10pt;
padding-right: 10px;
padding-bottom: 5px;
padding-top: 5px;
}
.lijst p {
font-size: 14px;
font-weight: bold;
}
.hide { display:none }
<input id="myInput" />
<ul id="myUL" style="">
<li class="lijst">
<p>NaamA PraktijkB</p>
<p>AdresA</p>
<p>logopedistA#Email.com</p>
<p>0612345678</p>
</li>
<li class="lijst">
<p>NaamC PraktijkD</p>
<p>AdresC</p>
<p>logopedistB#Email.com</p>
<p>0687654321</p>
</li>

Make dropdown visible only when function is called

I am trying make the drop-down visible only when something is entered in the search bar.Otherwise it stays collapsed. Following is my code
function mysearchFunction() {
var input, upperCase, ul, li, x, i, ax;
input = document.getElementById("mysearchInput");
upperCase = input.value.toUpperCase();
ul = document.getElementById("myList");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
x = li[i].getElementsByTagName("a")[0];
if (x.innerHTML.toUpperCase().indexOf(upperCase) === 0) {
li[i].style.visibility = "visible";
li[i].style.display = "block";
} else {
li[i].style.display = "none";
}
}
}
#myList li a {
border: 1px solid #ddd;
margin-top: -2px;
background-color: #f6f6f6;
padding: 10px;
text-decoration: none;
font-size: 16px;
color: black;
display: block;
visibility: collapse;
}
<input type="text" id="mysearchInput" onkeyup="mysearchFunction()" placeholder="Search..">
<ul id="myList">
<li>America</li>
<li>Africa</li>
<li>Antartica</li>
<li>Asia</li>
<li>Europe</li>
<li>Australia</li>
</ul>
In the JS, I am trying to make only content that needs to be displayed as visible. Kindly guide me where I am going wrong. No content is currently being displayed. It is staying collapsed.
Just updated the css selector: #myList li, you were hiding all the links.
function mysearchFunction() {
var input, upperCase, ul, li, x, i, ax;
input = document.getElementById("mysearchInput");
upperCase = input.value.toUpperCase();
//console.log(upperCase);
ul = document.getElementById("myList");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
x = li[i].getElementsByTagName("a")[0];
if (x.innerHTML.toUpperCase().indexOf(upperCase) == 0 && upperCase !== '') {
li[i].style.visibility = "visible";
li[i].style.display = "block";
} else {
li[i].style.display = "none";
}
}
}
#myList li {
border: 1px solid #ddd;
margin-top: -2px;
background-color: #f6f6f6;
padding: 10px;
text-decoration: none;
font-size: 16px;
color: black;
display: block;
visibility: collapse;
}
<input type="text" id="mysearchInput" onkeyup="mysearchFunction()" placeholder="Search..">
<ul id="myList">
<li>America</li>
<li>Africa</li>
<li>Antartica</li>
<li>Asia</li>
<li>Europe</li>
<li>Australia</li>
</ul>

Allow background-image url to be clickable

Is there a way to allow this (search) icon to be clickable? I would like it so that it can be used as an expand/collapse button for the list below it. The list is html and I can hide and show it. I'm more curious as to how I would allow the icon to be clickable to be able to hide/show the ul/li list. If this is possible, can an animation be applied somehow. This is a sample from w3 schools, but I have my own data. Should I convert it into a different type of list? There are examples online of retractable lists with animations as well.
function myFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
* {
box-sizing: border-box;
}
#myInput {
background-image: url('https://www.w3schools.com/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 0px;
}
#myUL {
list-style-type: none;
padding: 0;
margin: 0;
}
#myUL li a {
border: 1px solid #ddd;
margin-top: -1px; /* Prevent double borders */
background-color: #f6f6f6;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
display: block
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br><br>
<div>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
</div>
<ul id="myUL">
<li>Adele</li>
<li>Agnes</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
You can make clickable any DOM element by adding an event listener. In your example the icon is a background image of the input element, so you need to remove it from there and make it an independent image to interact with it. Then you can add the event listener to click, triggering a function to show / hide the list (I changed the css to start hidden).
var searchIco = document.getElementById("search-ico");
var myUL = document.getElementById("myUL");
searchIco.addEventListener("click", function() {
if(myUL.style.display == 'block') {
myUL.style.display = 'none';
// or: myUL.removeAttribute("style");
} else {
myUL.style.display = 'block';
}
});
function myFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
* {
box-sizing: border-box;
}
/* New */
#search-ico {
width: 16px;
height: 16px;
}
/* Background removed, size changed */
#myInput {
width: 80%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 0px;
}
#myUL {
display: none; /* Added to start hidden */
list-style-type: none;
padding: 0;
margin: 0;
}
#myUL li a {
border: 1px solid #ddd;
margin-top: -1px; /* Prevent double borders */
background-color: #f6f6f6;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
display: block
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br><br>
<div>
<!-- Add the icon as a separate image -->
<img id="search-ico" src="https://www.w3schools.com/css/searchicon.png">
<!-- end of edited -->
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
</div>
<ul id="myUL">
<li>Adele</li>
<li>Agnes</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
You can call the slideToggle function based on jQuery (since you are already using jQuery)
$('#myInput').click(function(){
$('#myUL').slideToggle('slow');
});
Learn more about sideToggle here - http://api.jquery.com/slidetoggle/

Trying to Fix the (Auto Search & Auto Sort ) Code with my current HTML code

I need some help, actually I am stuck with this school project. I am trying to use the attached code, creating an auto-search website. Initially i have trouble with sorting out the tables, but eventually was fixed. However, i still have the Auto Sort issue. If i search for something, e.g. i search for "1", a list of "1" will appear. However, i wanted the page to auto sort based on the highest value to the lowest (descending). Here are the edited codes: http://plnkr.co/edit/HeFy7mONHCJDweqi03Zp?p=preview
<!DOCTYPE html>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myUL {
list-style-type: none;
padding: 0;
margin: 0;
}
#myUL li a {
border: 1px solid #ddd;
margin-top: -1px; /* Prevent double borders */
background-color: #f6f6f6;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
display: block
}
#myUL ll a {
border: 1px solid #ddd;
margin-top: -1px; /* Prevent double borders */
background-color: #f6f6f6;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
display: block
}
#myUL li a.header {
background-color: #e2e2e2;
cursor: default;
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
</style>
</head>
<body>
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL">
<table border="0">
<tr>
<td><li>2000</li></td>
<td><ll>Hotmail</ll></td>
</tr>
<tr>
<td><li>3000</td>
<td><ll>Hotmail</ll></td>
</tr>
<tr>
<td><li>1000</li></td>
<td><ll>Hotmail</ll></td>
</tr>
<tr>
<td><li>1500</li></td>
<td><ll>Hotmail</ll></td>
</tr>
<tr>
<td><li>1400</li></td>
<td><ll>Hotmail</ll></td>
</tr>
<tr>
<td><li>2500</li></td>
<td><ll>Hotmail</ll></td>
</tr>
</table>
</ul>
<script>
function myFunction() {
var input, filter, ul, li, ll, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName("li");
ll = ul.getElementsByTagName("ll");
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
</script>
</body>
</html>
So am I right that you want to search for a Number (e.g. 2000) and the result should be: 2000 / Hotmail (matching your number)?
Edit: I saw u re not setting the display style for your 'll' elements.
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
ll[i].style.display = ""; // <- this is new
} else {
li[i].style.display = "none";
ll[i].style.display = "none"; // <- this is new
}}
Here is the live result: http://plnkr.co/edit/HeFy7mONHCJDweqi03Zp?p=info

Categories

Resources