Issue
My apologies if this has been answered elsewhere; if so, I was unable to query the database in a way that returned the result I need. Here's my question:
Let's say I have an unordered list of state names.
etc., Louisiana, Maine, Massachusetts, Michigan, Mississippi, Missouri, Montana, New Hampshire, etc.
And I want to display a search box that filters the list to a single choice as successive unique letters are typed in. In other words, by just typing in an "M", you eliminate "Louisiana" and "New Hampshire" from the list. By adding an "o" to the "M" you eliminate everything but "Montana." But typing in an "a" after the "M" the list still offers two choices. In order to reduce the list to a single choice you have to type a third letter. I've found a script that will filter by upper case letter, but nothing more. If a second letter is typed in to further reduce the number of choices, the list disappears entirely.
Here (from w3schools with some modification) are the elements:
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.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;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<ul id="myUL">
<li><a href="#">Louisiana</a></li>
<li><a href="#">Maine</a></li>
<li><a href="#">Massachusetts</a></li>
<li><a href="#">Michigan</a></li>
<li><a href="#">Mississippi</a></li>
<li><a href="#">Missouri</a></li>
<li><a href="#">Montana</a></li>
<li><a href="#">New Hampshire</a></li>
</ul>
Their script does offer the option of sorting by any letter in the name instead of just the uppercase (presumably first) letter. But this returns all names wherein the typed letter appears at all. Thus, typing an "i" (in a list of all state names) would display all states with that letter anywhere in the name. However, this method eventually does reduce the list to a single choice as more letters are typed in. I would like both of these methods to work together i.e., I want the first typed letter to filter the list to states with only that first letter, the second typed letter to reduce it to only those states with the same first two letters, etc. I hope that makes sense.
Thanks in advance for any help.
Solution
Is more algorithmic problem than javascript problem, so u can add aditional tag to your question. I used foreach loop to simplified code, u can change it if u want. Okej your code check if txtValue(string variable) contain second string 'filter' txtValue.indexOf(filter) > -1
, here u can read more about indexOf method.
You need to check, which option of your list start with 'filter'. Simplest solution for your will be:
function myFunction() {
var value = document.getElementById("myInput").value.toUpperCase();
var myUL = document.getElementById("myUL");
for (var elem of myUL.getElementsByTagName("li")) {
if (elem.innerText.toUpperCase().startsWith(value)) {
elem.style.display = "";
} else {
elem.style.display = "none";
}
}
}
but i don't think it is a good search engine. U can search "Fuzzy search algorithm" to achieve smth more sophisticated.
Answered By - Michał Łukasik
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.