Hide search elements in Javascript - javascript

In the following example code I want to hide the elements that show under the search field.
Code is from W3: https://www.w3schools.com/howto/howto_js_filter_lists.asp
Search elements should only show when users starts typing in the search field. Nothing complex just looking for solution for beginner. Thanks
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<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 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">
<li>Adele</li>
<li>Agnes</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
<script>
function myFunction() {
var input, filter, ul, li, a, 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++) {
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";
}
}
}
</script>
</body>
</html>

Just set display: none to #myUL li
#myUL li {
display: none;
}
and change in your js add li[i].style.display = "block"
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "block";
} else {
li[i].style.display = "none";
}
Working Example
function myFunction() {
var input, filter, ul, li, a, 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++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "block";
} else {
li[i].style.display = "none";
}
}
}
* {
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 {
display: none
}
#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;
}
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<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>
My approach would be different for making this search bar
const input = document.querySelector("input");
const listItems = document.querySelectorAll(".list-item");
input.addEventListener("input", (event) => {
const value = event.target.value;
listItems.forEach((listItem) => {
const target =
value.trim().length > 0 &&
listItem.innerText.toLowerCase().includes(value);
if (target === true) {
listItem.style.display = "block";
} else {
listItem.style.display = "none";
}
});
});
#import "https://cdn.jsdelivr.net/gh/KunalTanwar/normalize/css/normalize.inter.min.css";
body {
height: 100%;
display: grid;
place-items: center;
}
.container {
--space: 4px;
--border-color: #e1e1e1;
width: 100%;
display: flex;
max-width: 480px;
flex-direction: column;
row-gap: calc(var(--space) * 2);
}
.container input {
border: 0;
padding: calc(var(--space) * 4);
box-shadow: inset 0 0 0 1px var(--border-color);
transition: box-shadow 125ms ease;
}
.container input:focus {
--border-color: #2e86c1;
}
.container ul {
display: inherit;
row-gap: var(--space);
flex-direction: inherit;
}
.container ul .list-item {
display: none;
text-transform: capitalize;
padding: calc(var(--space) * 4);
box-shadow: inset 0 0 0 1px var(--border-color);
}
<div class="container">
<input type="text" placeholder="Search for names" />
<ul>
<li class="list-item">adele</li>
<li class="list-item">agnes</li>
<li class="list-item">billy</li>
<li class="list-item">bob</li>
<li class="list-item">calvin</li>
<li class="list-item">christina</li>
<li class="list-item">cindy</li>
</ul>
</div>
Now in my approach if your input is empty no list-item is visible.

Not the elegant solutions but useful to help you to understand how that scripts works, add style="display:none" to the li from the start:
<ul id="myUL">
<li style="display:none">Adele</li>
<li style="display:none">Agnes</li>
<li style="display:none">Billy</li>
<li style="display:none">Bob</li>
<li style="display:none">Calvin</li>
<li style="display:none">Christina</li>
<li style="display:none">Cindy</li>
</ul>

Related

How to get my auto complete to display after typing in a letter or word

Right now all my words are displayed before you even start typing. I would like the words to display after you start typing. Im having a brain fart on how to make the words remain hidden until you start typing a letter and then it filters the results based on what you type.
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<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>
<script>
function myFunction() {
var input, filter, ul, li, a, 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++) {
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";
}
}
}
</script>
css
* {
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 li a:hover:not(.header) {
background-color: #eee;
}
First, to hide from start, pure CSS
#myUL li {
display: none
}
Then when typing with it never hides (if not having the CSS above) because you don't set anything in display when there is a match li[i].style.display = "", change to li[i].style.display = "block" and test if input.value has some length like this:
li[i].style.display = input.value.length && txtValue.toUpperCase().indexOf(filter) > -1 ? "block" : "none";
also you are checking for text inside a, no need for that, you can check for text in the li
function myFunction() {
const input = document.getElementById("myInput");
const filter = input.value.toUpperCase();
const ul = document.getElementById("myUL");
const li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
const txtValue = li[i].textContent || li[i].innerText;
li[i].style.display = input.value.length && txtValue.toUpperCase().indexOf(filter) > -1 ? "block" : "none";
}
}
myInput.addEventListener('keyup', myFunction)
* {
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 {
display: none
}
#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;
}
<h2>My Phonebook</h2>
<input type="text" id="myInput" placeholder="Search for names.." title="Type in a name">
<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 achieve this by initially hiding the list and checking the length of your input variable afterward. If the length is greater than zero, append a class show. Else, remove the class again. In Vanilla JS, you can do this by accessing the elements classList.
function myFunction() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
if (filter.length > 0) {
ul.classList.add('show');
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";
}
}
} else {
ul.classList.remove('show');
}
}
* {
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;
display: none;
}
#myUL.show {
display: block;
}
#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;
}
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<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>

Sorting and Display Search Results Without Display them First

I have the Tables Sort Script which sort results.
However, i want the script to sort and display results AFTER the search.
I mean, instead of this display:
It will show only the search input (without results):
So only AFTER i enter some text in the input, THEN i will got the immidiat results:
Here's the code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<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 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">
<li>Adele</li>
<li>Agnes</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
<script>
function myFunction() {
var input, filter, ul, li, a, 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++) {
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";
}
}
}
</script>
</body>
</html>
Got it:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<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 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"></ul>
<script>
function myFunction() {
var items = ['Adele', 'Agnes', 'Billy', 'Bob', 'Calvin', 'Christina', 'Cindy'];
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById('myUL');
ul.innerHTML = '';
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (filter && item.toUpperCase().includes(filter.toUpperCase())) {
ul.innerHTML += `<li>${item}</li>`;
}
}
}
</script>
</body>
</html>

Why is search bar changing position of headers?

I am creating an HTML/CSS/JS project with a search bar and a header. When the search bar is activated/deactivated (clicked on), it changes the position of my headers. How can I fix this issue and keep the headers in the same position? Thanks a lot!
function myFunction() {
var input, filter, ul, li, a, 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++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1 && filter != "") {//change here
li[i].style.display = "";
li[i].style.visibility = "visible";//change here
} else {
li[i].style.display = "none";
}
}
}
body {
background-image: url('paperforrite-removebg-preview.png');
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 500px;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
border-radius: 4px;
}
#myUL {
list-style-type: none;
padding: 0;
margin: 0;
width: 558px;
}
#myUL li a {
border: 1px solid #ddd;
margin-top: -1px;
background-color: #f6f6f6;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
display: block;
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." style="font-family: 'Poppins', sans-serif;">
<ul id="myUL" style="visibility: hidden">
<li>Adele</li>
<li>Agnes</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
<br>
<br>
<h1><center style="font-family: 'Poppins', sans-serif; font-size: 100px; color: #000000;">Some text here</center></h1>
<br>
<br>
<h2><center style="font-family: 'Poppins', sans-serif; font-size: 20px; color: #000000;">Some text here</center></h2>
Just add position: absolute; to the #myUl css tag, like shown below.
Your current ul tag is part of the flow and thus push everything down.
At first, it pushes everything down because it has visibility: hidden, which renders the ul with its height/width.
Then, when you type in the search bar, your javascript kicks in, which in turn hides the block with display: none, removing its block property and not making it render the height/width.
If you wish to keep the block behavior (push down the header), just switch the visibility: hidden to display: none in the ul html.
function myFunction() {
var input, filter, ul, li, a, 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++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1 && filter != "") {//change here
li[i].style.display = "";
li[i].style.visibility = "visible";//change here
} else {
li[i].style.display = "none";
}
}
}
body {
background-image: url('paperforrite-removebg-preview.png');
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 500px;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
border-radius: 4px;
}
#myUL {
list-style-type: none;
padding: 0;
margin: 0;
width: 558px;
position: absolute;
}
#myUL li a {
border: 1px solid #ddd;
margin-top: -1px;
background-color: #f6f6f6;
padding: 12px;
text-decoration: none;
font-size: 18px;
color: black;
display: block;
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." style="font-family: 'Poppins', sans-serif;">
<ul id="myUL" style="visibility: hidden">
<li>Adele</li>
<li>Agnes</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
<br>
<br>
<h1><center style="font-family: 'Poppins', sans-serif; font-size: 100px; color: #000000;">Some text here</center></h1>
<br>
<br>
<h2><center style="font-family: 'Poppins', sans-serif; font-size: 20px; color: #000000;">Some text here</center></h2>

How to hide search results when clearing out in the input search box? JavaScript Only Please

How do you clear search results when clearing out inside the input text box? I have tried this answer on stackoverflow- How to hide the List items from Search Filter, when search input field is cleared?. Unfortunately, it does not work in this particular coding
function myFunction() {
var query = document.querySelector('#myInput').value;
// this wil grab all <li> elements from all <ul> elements on the page
// however, you will want to specify a unique attribute for only the elements you wish to include
var elements = document.querySelectorAll('li');
for (var i = 0; i < elements.length; i ++) {
var el = elements[i];
if (el.innerText.indexOf(query) !== -1)
el.style.display = 'block';
else
el.style.display = 'none';
}
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 10px;
border: 1px solid #ddd;
}
#myUL, #myUL2 {
list-style-type: none;
padding: 0px;
margin: 0px;
margin-top:10px;
}
#myUL li, #myUL2 li {
list-style-type: none;
border: 1px solid #ddd;
padding:5px;
background-color: #f6f6f6;
text-decoration: none;
font-size: 18px;
color: black;
margin-bottom:5px;
}
#myUL li, #myUL2 li {
display: none;
}
#myUL li a:hover:not(.header), #myUL2 li a:hover:not(.header) {
background-color: #eee;
}
<h2>
Test Search
</h2>
<p>
How to hide the List items from Search Filter, when search input field is cleared?</p>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="search" autocomplete="off">
<ul id="myUL" class="ul1">
<li>bob <div>
description
</div>
<div>
another description
</div>
</li>
<li>rob ss</li>
<li>tom</li>
<li>mark</li>
</ul>
<ul id="myUL2" class="ul2">
<li>purse</li>
<li>cat</li>
<li>pencil</li>
<li>sharpner</li>
</ul>
Please use JavaScript only. Thank you for any assistance. Greatly appreciated.
You can check if query is defined and not empty when displaying or hiding an element.
if (query && el.innerText.indexOf(query) !== -1)
When search box is cleared, query will be empty and this condition evaluates to false and all elements will be hidden.
Live Example:
function myFunction() {
var query = document.querySelector('#myInput').value;
// this wil grab all <li> elements from all <ul> elements on the page
// however, you will want to specify a unique attribute for only the elements you wish to include
var elements = document.querySelectorAll('li');
for (var i = 0; i < elements.length; i ++) {
var el = elements[i];
if (query && el.innerText.indexOf(query) !== -1)
el.style.display = 'block';
else
el.style.display = 'none';
}
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 10px;
border: 1px solid #ddd;
}
#myUL, #myUL2 {
list-style-type: none;
padding: 0px;
margin: 0px;
margin-top:10px;
}
#myUL li, #myUL2 li {
list-style-type: none;
border: 1px solid #ddd;
padding:5px;
background-color: #f6f6f6;
text-decoration: none;
font-size: 18px;
color: black;
margin-bottom:5px;
}
#myUL li, #myUL2 li {
display: none;
}
#myUL li a:hover:not(.header), #myUL2 li a:hover:not(.header) {
background-color: #eee;
}
<h2>
Test Search
</h2>
<p>
How to hide the List items from Search Filter, when search input field is cleared?</p>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="search" autocomplete="off">
<ul id="myUL" class="ul1">
<li>bob <div>
description
</div>
<div>
another description
</div>
</li>
<li>rob ss</li>
<li>tom</li>
<li>mark</li>
</ul>
<ul id="myUL2" class="ul2">
<li>purse</li>
<li>cat</li>
<li>pencil</li>
<li>sharpner</li>
</ul>
You can achieve this by adding this three lines:
let status = query === "" ? "none" : "block" //If input value is empty, set to "none"
document.querySelector("#myUL").style.display = status;
document.querySelector("#myUL2").style.display = status;
This will hide both of your divs whenever your input is empty. Otherwise, it will always be shown.
Look at the new example:
function myFunction() {
var query = document.querySelector('#myInput').value;
// this wil grab all <li> elements from all <ul> elements on the page
// however, you will want to specify a unique attribute for only the elements you wish to include
var elements = document.querySelectorAll('li');
let status = query==="" ? "none" : "block"
document.querySelector("#myUL").style.display = status;
document.querySelector("#myUL2").style.display = status;
for (var i = 0; i < elements.length; i++) {
var el = elements[i];
if (el.innerText.indexOf(query) !== -1)
el.style.display = 'block';
else
el.style.display = 'none';
}
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 10px;
border: 1px solid #ddd;
}
#myUL,
#myUL2 {
list-style-type: none;
padding: 0px;
margin: 0px;
margin-top: 10px;
}
#myUL li,
#myUL2 li {
list-style-type: none;
border: 1px solid #ddd;
padding: 5px;
background-color: #f6f6f6;
text-decoration: none;
font-size: 18px;
color: black;
margin-bottom: 5px;
}
#myUL li,
#myUL2 li {
display: none;
}
#myUL li a:hover:not(.header),
#myUL2 li a:hover:not(.header) {
background-color: #eee;
}
<h2>
Test Search
</h2>
<p>
How to hide the List items from Search Filter, when search input field is cleared?</p>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="search" autocomplete="off">
<ul id="myUL" class="ul1">
<li>bob
<div>
description
</div>
<div>
another description
</div>
</li>
<li>rob ss</li>
<li>tom</li>
<li>mark</li>
</ul>
<ul id="myUL2" class="ul2">
<li>purse</li>
<li>cat</li>
<li>pencil</li>
<li>sharpner</li>
</ul>
You can reset all of the elements before applying your filter logic that decides which elements to show. Here's an example:
function myFunction() {
var query = document.querySelector('#myInput').value;
var elements = Array.from(document.querySelectorAll('li'));
// Reset all the elements.
elements.forEach(li => li.style.display = 'none');
// Show the elements that contain the query text.
elements
.filter(li => query && li.innerText.indexOf(query) >= 0)
.forEach(li => li.style.display = 'block');
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 10px;
border: 1px solid #ddd;
}
#myUL, #myUL2 {
list-style-type: none;
padding: 0px;
margin: 0px;
margin-top:10px;
}
#myUL li, #myUL2 li {
list-style-type: none;
border: 1px solid #ddd;
padding:5px;
background-color: #f6f6f6;
text-decoration: none;
font-size: 18px;
color: black;
margin-bottom:5px;
}
#myUL li, #myUL2 li {
display: none;
}
#myUL li a:hover:not(.header), #myUL2 li a:hover:not(.header) {
background-color: #eee;
}
<h2>
Test Search
</h2>
<p>
How to hide the List items from Search Filter, when search input field is cleared?</p>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="search" autocomplete="off">
<ul id="myUL" class="ul1">
<li>bob <div>
description
</div>
<div>
another description
</div>
</li>
<li>rob ss</li>
<li>tom</li>
<li>mark</li>
</ul>
<ul id="myUL2" class="ul2">
<li>purse</li>
<li>cat</li>
<li>pencil</li>
<li>sharpner</li>
</ul>
This example uses the array filter() and forEach() methods. You can learn about those here and here, respectively. Otherwise, feel free to use your loop.

Show Hide <li> Elements

I am creating a simple html search box with live list filtering. The user will enter text in search box and the list will filter according to the user entered data. The problem I am facing is that my list is not showing up after I used the code to hide the "li" elements. As for the hiding list part the css is working its function very accurately but the query function is not listing up the results. Here is the Code...
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");
$(".menu-hide").show(); // <-- code to show the list
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('/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 li a:hover:not(.header) {
background-color: #eee;
}
.menu-hide {
display: none;
}
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL" class="menu-hide">
<li>John</li>
<li>Angela</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
sorry for the long code because as a student I am new to asking question prciesly.
You have lots more code there than needed, and only a single line of jQuery, which is easily eliminated.
Also, your demo doesn't actually load the jQuery library, so that would be an issue
Here's a rewrite that maintains something close to your initial approach, but simplifies the DOM selection using querySelectorAll, and drops the unnecessary library.
Click for demo...
function myFunction() {
var filter = document.getElementById("myInput").value.toUpperCase().trim();
document.querySelector(".menu-hide").style.display = filter ? "block" : "none";
var a = document.querySelectorAll("#myUL li a");
for (var i = 0; i < a.length; i++) {
if (a[i].textContent.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
}
* {
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 li a:hover:not(.header) {
background-color: #eee;
}
.menu-hide {
display: none;
}
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL" class="menu-hide">
<li>John</li>
<li>Angela</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>
Here's one that reworks it to further shorten and simplify it. It uses a for-of loop to iterate the collection, and the conditional operator to set the .display.
Click for demo...
function myFunction() {
var filter = document.getElementById("myInput").value.toUpperCase().trim();
document.querySelector(".menu-hide").style.display = filter ? "block" : "none";
for (const a of document.querySelectorAll("#myUL li a")) {
a.style.display =
a.textContent.toUpperCase().includes(filter) ? "block" : "";
}
}
* {
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: none;
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
<h2>My Phonebook</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL" class="menu-hide">
<li>John</li>
<li>Angela</li>
<li>Billy</li>
<li>Bob</li>
<li>Calvin</li>
<li>Christina</li>
<li>Cindy</li>
</ul>

Categories

Resources