th_22
th_22

Reputation: 1

CSS drop-down menu with search function - pinning search bar to top

I'm trying to make it so the search box (#myInput) in this drop-down menu is pinned to the top as users scroll through the selection menu, similar to "freezing" a row in Excel.

Is it possible to have this functionality using CSS without completely separating the search box from the menu options? Or will I have to look at other options to keep the search box pinned?

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";
    }
  }
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">.dropbtn {
  background-color: #A41E34;
  color: white;
  padding: 16px;
  font-size: 18px;
  border: none;
  cursor: pointer;
}

.dropdown:hover .dropdown-content {
  display: block;
}

#myInput {
  box-sizing: border-box;
  background-color: #FFFFFF;
  min-width: 100%;
  font-size: 18px;
  padding: 14px 20px 12px 20px;
  border: none;
}

#myInput:focus {outline: 1px solid #ddd;}

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

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f6f6f6;
  min-width: 100%;
  max-height: 420px;
  overflow: auto;
  font-size: 18px;
  border: 1px solid #ddd;
  z-index: 1;
}

.dropdown-content a {
  color: black;
  padding: 16px 20px;
  min-width: 100%;
  text-decoration: none;
  display: block;
}

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

.show {display: block;}
</style>
<div class="dropdown"><button class="dropbtn" onclick="myFunction()">Select an Option</button>
    <div class="dropdown-content" id="myDropdown"><input id="myInput" onkeyup="filterFunction()" placeholder="Search..." type="text"> <a href="https://www.google.com">Option 1</a> <a href="https://www.google.com">Option 2</a> <a href="https://www.google.com">Option 3</a> <a href="https://www.google.com">Option 4</a> <a href="https://www.google.com">Option 5</a> <a href="https://www.google.com">Option 6</a> <a href="https://www.google.com">Option 7</a> <a href="https://www.google.com">Option 8</a> <a href="https://www.google.com">Choice 1</a> <a href="https://www.google.com">Choice 2</a> <a href="https://www.google.com">Choice 3</a> <a href="https://www.google.com">Choice 4</a></div>

Upvotes: 0

Views: 719

Answers (2)

karolus
karolus

Reputation: 922

To modify your code, all I did was add two lines to the CSS for the #myInput element. Without the top margin removed, there was a bit of text showing when scrolling through the list. I also added padding to the second child element, based on the values of the text size + top and bottom padding.

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";
    }
  }
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">.dropbtn {
  background-color: #A41E34;
  color: white;
  padding: 16px;
  font-size: 18px;
  border: none;
  cursor: pointer;
}

.dropdown:hover .dropdown-content {
  display: block;
}

#myInput {
  box-sizing: border-box;
  background-color: #FFFFFF;
  width: initial;
  font-size: 18px;
  padding: 14px 20px 12px 20px;
  border: none;
  position: sticky;
  display: block;
  top: 0;
  margin-top: 0;
}

#myInput:focus {outline: 1px solid #ddd;}

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

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f6f6f6;
  min-width: 100%;
  max-height: 420px;
  overflow: auto;
  font-size: 18px;
  border: 1px solid #ddd;
  z-index: 1;
}

.dropdown-content a {
  color: black;
  padding: 16px 20px;
  min-width: 100%;
  text-decoration: none;
  display: block;
}

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

.show {display: block;}
</style>
<div class="dropdown"><button class="dropbtn" onclick="myFunction()">Select an Option</button>
    <div class="dropdown-content" id="myDropdown"><input id="myInput" onkeyup="filterFunction()" placeholder="Search..." type="text"> <a href="https://www.google.com">Option 1</a> <a href="https://www.google.com">Option 2</a> <a href="https://www.google.com">Option 3</a> <a href="https://www.google.com">Option 4</a> <a href="https://www.google.com">Option 5</a> <a href="https://www.google.com">Option 6</a> <a href="https://www.google.com">Option 7</a> <a href="https://www.google.com">Option 8</a> <a href="https://www.google.com">Choice 1</a> <a href="https://www.google.com">Choice 2</a> <a href="https://www.google.com">Choice 3</a> <a href="https://www.google.com">Choice 4</a></div>

Upvotes: 1

rensothearin
rensothearin

Reputation: 766

As other way around, you can use Bootstrap-Select plugin. It has all the thing. Check it here.

Upvotes: 0

Related Questions