1

I am working on a searchable dropdown and here is my code:

function openSearchDropdown() {
    document.getElementById("myDropdown").classList.toggle("show");
}

function closeSearchDropdown() {
    document.getElementById("myDropdown").classList.toggle("show");
}

function selectFilteredValue() {
    document.getElementById("search_input").value = event.target.getAttribute("data-value");
    closeSearchDropdown();
}

function filterSearchDropdown() {
    var input, filter, ul, li, span, i;
    input = document.getElementById("search_value");
    filter = input.value.toUpperCase();
    div = document.getElementById("myDropdown");
    span = div.getElementsByTagName("span");
    for (i = 0; i < span.length; i++) {
        txtValue = span[i].textContent || span[i].innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
            span[i].style.display = "";
        } else {
            span[i].style.display = "none";
        }
    }
}
.dropdown .search-area {
    box-sizing: border-box;
    background-image: url("searchicon.png");
    background-position: 14px 12px;
    background-repeat: no-repeat;
    font-size: 16px;
    padding-top:5px;
    border: none;
    border-bottom: 1px solid #ddd;
}

.dropdown .search-area:focus {
    outline: 3px solid #ddd;
}

.dropdown {
    position: relative;
    display: inline-block;
    left:35px;
}

.dropdown-content {
    display: none;
    position: absolute;
    overflow: auto;
    border: 1px solid #ddd;
    z-index: 1;
}

.dropdown-content span {
    color: black;
    padding-top:5px;
    text-decoration: none;
    display: block;
}

.dropdown span:hover {
    background-color: #ddd;
}

.show {
    display: block;
}
input#search_input {
    min-width: 191px;
}
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>

        <div class="dropdown">
            <input onclick="openSearchDropdown()" id="search_input" />
            <div id="myDropdown" class="dropdown-content">
                <input type="text" placeholder="Search.." id="search_value" onkeyup="filterSearchDropdown()" class="search-area" />
                <span data-value="Bangkok" onclick="selectFilteredValue()">Bangkok</span>
                <span data-value="Hong_Kong" onclick="selectFilteredValue()">Hong_Kong</span>
                <span data-value="Jakarta" onclick="selectFilteredValue()">Jakarta</span>
                <span data-value="Delhi" onclick="selectFilteredValue()">Delhi</span>
                <span data-value="Karachi" onclick="selectFilteredValue()">Karachi</span>
                <span data-value="Sydney" onclick="selectFilteredValue()">Sydney</span>
            </div>
        </div>
    </body>
</html>

This works fine. I just need to add a scrollbar and a down arrow when the list is open. I need like this.

Any help or suggestion would be appreciated.

enter image description here

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
Owais Ahmed
  • 1,364
  • 1
  • 30
  • 62

2 Answers2

1

There will automatically be a dropdown if the height of the drop down is less than the height of all of the options available. This is the CSS required, there is a snippet included below so you can see what it looks like.

/* change 5 to the number of items you want to show at start of dropdown */
 /* 1em = font height, 8px from outline + padding*/
 /* max-height and not height for when search has less results */
 
#myDropdown {
  max-height: calc(4 * (1em + 8px));
}

/* rest of your css */

function openSearchDropdown() {
    document.getElementById("myDropdown").classList.toggle("show");
}

function closeSearchDropdown() {
    document.getElementById("myDropdown").classList.toggle("show");
}

function selectFilteredValue() {
    document.getElementById("search_input").value = event.target.getAttribute("data-value");
    closeSearchDropdown();
}

function filterSearchDropdown() {
    var input, filter, ul, li, span, i;
    input = document.getElementById("search_value");
    filter = input.value.toUpperCase();
    div = document.getElementById("myDropdown");
    span = div.getElementsByTagName("span");
    for (i = 0; i < span.length; i++) {
        txtValue = span[i].textContent || span[i].innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
            span[i].style.display = "";
        } else {
            span[i].style.display = "none";
        }
    }
}
/* change 5 to the number of items you want to show at start of dropdown */
 /* 1em = font height, 8px from outline + padding*/
 /* max-height and not height for when search has less results */
 
#myDropdown {
  max-height: calc(4 * (1em + 8px));
}

/* rest of your css */

.dropdown .search-area {
    box-sizing: border-box;
    background-image: url("searchicon.png");
    background-position: 14px 12px;
    background-repeat: no-repeat;
    font-size: 16px;
    padding-top:5px;
    border: none;
    border-bottom: 1px solid #ddd;
}

.dropdown .search-area:focus {
    outline: 3px solid #ddd;
}

.dropdown {
    position: relative;
    display: inline-block;
    left:35px;
}

.dropdown-content {
    display: none;
    position: absolute;
    overflow: auto;
    border: 1px solid #ddd;
    z-index: 1;
}

.dropdown-content span {
    color: black;
    padding-top:5px;
    text-decoration: none;
    display: block;
}

.dropdown span:hover {
    background-color: #ddd;
}

.show {
    display: block;
}
input#search_input {
    min-width: 191px;
}
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>

        <div class="dropdown">
            <input onclick="openSearchDropdown()" id="search_input" />
            <div id="myDropdown" class="dropdown-content">
                <input type="text" placeholder="Search.." id="search_value" onkeyup="filterSearchDropdown()" class="search-area" />
                <span data-value="Bangkok" onclick="selectFilteredValue()">Bangkok</span>
                <span data-value="Hong_Kong" onclick="selectFilteredValue()">Hong_Kong</span>
                <span data-value="Jakarta" onclick="selectFilteredValue()">Jakarta</span>
                <span data-value="Delhi" onclick="selectFilteredValue()">Delhi</span>
                <span data-value="Karachi" onclick="selectFilteredValue()">Karachi</span>
                <span data-value="Sydney" onclick="selectFilteredValue()">Sydney</span>
            </div>
        </div>
    </body>
</html>
Alvie Mahmud
  • 194
  • 1
  • 10
0

I think this question is not related to javascript. What you need to do is to set a fixed max-height CSS property to #myDropdown element and that will cause an overflow when excessive number of elements are rendered. And as you have overflow: auto, it will prompt the scrollbar in that div. How to modify it? With CSS too, you can look how here and here

Agustin Moles
  • 1,364
  • 7
  • 15