Make only 5 results to be visible in a search bar at a time

Viewed 445

I have an search bar which is working perfectly. But getting an issue. I want only 5 results to be vsible at a time and other results should be seen by sliding from the slider. For example if it contains 10 results. Then is shoould show ony 5 on searching and to see other user can sllide from the slidebar.... here is my code

function filterFunction() {
  let isInputAvail = false;
  var input, filter, ul, li, a, i;
  input = document.getElementById("myInput");
  filter = input.value.toLowerCase();
  if (filter.length > 0) {
    document.getElementById("myDropdown").classList.add("show");
  } else {
    document.getElementById("myDropdown").classList.remove("show");
  }
  div = document.getElementById("myDropdown");
  a = div.getElementsByTagName("a");
  for (i = 0; i < a.length; i++) {
    txtValue = a[i].innerText;
    if (txtValue.toLowerCase().indexOf(filter) > -1) {
      isInputAvail = true;
      a[i].style.display = "block";
    } else {
      a[i].style.display = "none";
    }
  }
  if (!isInputAvail) {
    document.getElementById("noMatches").classList.add('show');
  } else {
    document.getElementById("noMatches").classList.remove('show');
  }
}
.div {
  display: none;
}

.dropbtn {
  padding: 16px;
  font-size: 16px;
  border: none;
  cursor: pointer;
  border-radius: 25px;
}

#myInput {
  box-sizing: border-box;
  background-position: 14px 12px;
  background-repeat: no-repeat;
  font-size: 16px;
  padding: 14px 20px 12px 45px;
  border: 5px solid #ddd;
  border-radius: 25px;
}

#myInput:focus {
  outline: 4px solid #f2f2f2;
  border-color: #171313;
}

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

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f6f6f6;
  min-width: 230px;
  overflow: auto;
  border: none;
  z-index: 1;
  border-radius: 25px;
}

.dropdown-content a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

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

.show {
  display: block;
}
<div class="dropdown">
  <input type="text" class="dropbtn" placeholder="Search Here..." id="myInput" onInput="filterFunction()">
  <div id="myDropdown" class="dropdown-content">
    <a href="#">Result 1</a>
    <a href="#">Result 2</a>
    <a href="#">Result 3</a>
    <a href="#">Result 4</a>
    <a href="#">Result 5</a>
    <a href="#">Result 6</a>
    <a href="#">Result 7</a>
    <a href="#">Result 8</a>
    <a href="#">Result 9</a>
    <a href="#">Result 10</a>
    <a href="#">Result 11</a>
    <a href="#">Result 12</a>
    <a href="#">Result 13</a>
    <a href="#">Result 14</a>
    <a href="#">Result 15</a>
  </div>
  <div id="noMatches" class="dropdown-content">
    <a href="#tools">No Matches</a>
  </div>
</div>

Here i want that when i write result then all the matching result is shown but that show a huge list. I want to make it to show ony 5 result and there should be a slidebar at right side from which on sliding other results can be seen. Hope you got my point. Thanks in advance.

2 Answers

Check out this snippet:

function filterFunction() {
    let isInputAvail = false;
    var input, filter, ul, li, a, i;
    input = document.getElementById("myInput");
    filter = input.value.toLowerCase();
    if (filter.length > 0) {
        document.getElementById("myDropdown").classList.add("show");
    } else {
        document.getElementById("myDropdown").classList.remove("show");
    }
    div = document.getElementById("myDropdown");
    a = div.getElementsByTagName("a");
    for (i = 0; i < a.length; i++) {
        txtValue = a[i].innerText;
        if (txtValue.toLowerCase().indexOf(filter) > -1) {
            isInputAvail = true;
            a[i].style.display = "block";
        } else {
            a[i].style.display = "none";
        }
    }
    if (!isInputAvail) {
        document.getElementById("noMatches").classList.add('show');
    } else {
        document.getElementById("noMatches").classList.remove('show');
    }
}
.div {
    display: none;
}

.dropbtn {
    padding: 16px;
    font-size: 16px;
    border: none;
    cursor: pointer;
    border-radius: 25px;
}

#myInput {
    box-sizing: border-box;
    background-position: 14px 12px;
    background-repeat: no-repeat;
    font-size: 16px;
    padding: 14px 20px 12px 45px;
    border: 5px solid #ddd;
    border-radius: 25px;
}

#myInput:focus {
    outline: 4px solid #f2f2f2;
    border-color: #171313;
}

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

.dropdown-content {
    max-height: 215px;
    display: none;
    position: absolute;
    background-color: #f6f6f6;
    min-width: 230px;
    overflow-y: scroll;
    border: none;
    z-index: 1;
    border-radius: 25px;
}

.dropdown-content a {
    color: black;
    padding: 12px 16px;
    text-decoration: none;
    display: block;
}

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

.show {
    display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Test</title>
</head>
<body>
    <div class="dropdown">
        <input type="text" class="dropbtn" placeholder="Search Here..." id="myInput" onInput="filterFunction()">
        <div id="myDropdown" class="dropdown-content">
            <a href="#">Result 1</a>
            <a href="#">Result 2</a>
            <a href="#">Result 3</a>
            <a href="#">Result 4</a>
            <a href="#">Result 5</a>
            <a href="#">Result 6</a>
            <a href="#">Result 7</a>
            <a href="#">Result 8</a>
            <a href="#">Result 9</a>
            <a href="#">Result 10</a>
            <a href="#">Result 11</a>
            <a href="#">Result 12</a>
            <a href="#">Result 13</a>
            <a href="#">Result 14</a>
            <a href="#">Result 15</a>
        </div>
        <div id="noMatches" class="dropdown-content">
            <a href="#tools">No Matches</a>
        </div>
    </div>
</body>
</html>

I have limited maximum height of .dropdown-content using max-height property and set vertical overflow to scroll using overflow-y: scroll;. Removed overflow: auto from .dropdown-content.

  • Don't use IDs, programming should be writing reusable code.
  • To show the dropdowns or to switch the list/no-matches, use two classes on the parent element ("hasvalue" and "nomatch"), the rest is all pure CSS and the :focus selector
  • Use CSS max-height to limit the height of your overflow element
  • UI/UX tip: half-cut the last list word, to additionally give the user a clue that there's more items in the scrollable element.

function dropdown(EL) {
  const EL_input = EL.querySelector(".dropdown-input");
  const ELS_li = EL.querySelectorAll(".dropdown-box--list a");
  const filter = () => {
    const val = EL_input.value.trim().toLowerCase();
    const fil = [...ELS_li].filter(el => {
      const match = el.textContent.trim().toLowerCase().includes(val);
      el.classList.toggle("hide", !match);
      return match;
    });
    EL.classList.toggle("hasvalue", val.length);
    EL.classList.toggle("nomatch", val.length && !fil.length);
  };

  EL_input.addEventListener("input", filter);
  EL_input.addEventListener("focus", filter);
  ELS_li.forEach(el => el.addEventListener("mousedown", () => {
    EL_input.value = el.textContent.trim()
  }));
}

document.querySelectorAll(".dropdown").forEach(el => dropdown(el));
/* QuickReset */ * {margin: 0; box-sizing: border-box;}


/* DROPDOWN COMPONENT */

.dropdown {
  --item-height: 30px;
  --visible: 5;
  font-family: sans-serif;
  position: relative;
  display: inline-block;
}

.dropdown-input {
  padding: 16px;
  font-size: 16px;
  border: none;
  cursor: pointer;
  font-size: 16px;
  padding: 15px 20px;
  border: 5px solid #ddd;
  border-radius: 25px;
  background: #fff;
}

.dropdown-input:focus {
  outline: none;
  border-color: #000;
}

.dropdown.hasvalue .dropdown-input:focus {
  border-bottom: 1px solid #ddd;
  border-radius: 25px 25px 0 0;
}

.dropdown-box {
  display: none;
  position: absolute;
  top: 100%;
  z-index: 1;
  min-width: 100%;
  overflow: auto;
  border-radius: 0 0 10px 10px;
  max-height: calc(var(--item-height) * var(--visible));
  border: 5px solid #000;
  border-top: 0;
}

.dropdown.hasvalue .dropdown-input:focus~.dropdown-box--list {
  display: block;
}

.dropdown.nomatch .dropdown-input:focus~.dropdown-box--list {
  display: none;
}

.dropdown.nomatch .dropdown-input:focus~.dropdown-box--nomatch {
  display: block !important;
}

.dropdown-box a {
  display: flex;
  align-items: center;
  padding: 7px 20px;
  min-height: var(--item-height);
  color: black;
  text-decoration: none;
  transition: background 0.24s;
}

.dropdown-box a.hide {
  display: none;
}

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

.dropdown-box::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.dropdown-box::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 10px;
}

.dropdown-box::-webkit-scrollbar-thumb {
  background-color: #000;
  border-radius: 10px;
}
<div class="dropdown">
  <input type="text" class="dropdown-input" autocomplete="off" placeholder="&#x1F50D;&#xfe0e; Search...">
  <div class="dropdown-box dropdown-box--list">
    <a href="#">Result 1</a>
    <a href="#">Result 2</a>
    <a href="#">Result 3</a>
    <a href="#">Result 4</a>
    <a href="#">Result 5</a>
    <a href="#">Result 6</a>
    <a href="#">Result 7</a>
    <a href="#">Result 8</a>
    <a href="#">Result 9</a>
    <a href="#">Result 10</a>
    <a href="#">Result 11</a>
    <a href="#">Result 12</a>
    <a href="#">Result 13</a>
    <a href="#">Result 14</a>
    <a href="#">Result 15</a>
  </div>
  <div class="dropdown-box dropdown-box--nomatch">
    <a href="#tools"><i>No Matches</i></a>
  </div>
</div>


<div class="dropdown">
  <input type="text" class="dropdown-input" autocomplete="off" placeholder="&#x1F50D;&#xfe0e; Yet another...">
  <div class="dropdown-box dropdown-box--list">
    <a href="#">Lorem</a>
    <a href="#">Ipsum</a>
    <a href="#">Dolor sit amet</a>
    <a href="#">Lorem ut florem</a>
  </div>
  <div class="dropdown-box dropdown-box--nomatch">
    <a href="#tools"><i>No Matches</i></a>
  </div>
</div>

Related