<div id="blog-geolytix-search" class="input-drop">
<input type="text" placeholder="Search places"></input>
<ul></ul>
</div>
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
border: 1px solid red;
padding: 10px;
}
:focus {
outline: none;
}
input {
width: 100%;
}
input[type="text"] {
border: 1px solid #ccc;
padding: 3px;
}
.input-drop {
width: 100%;
overflow: visible;
position: relative;
box-shadow: 1px 1px 3px 0 #ddd;
margin: 5px 0;
&:disabled {
pointer-events: none;
opacity: 0.4;
}
input[type="text"] {
width: 100%;
text-overflow: ellipsis;
padding: 5px;
border: 1px solid #ccc;
}
ul {
width: 100%;
margin-top: -2px;
max-height: 0;
transition: max-height 0.3s ease-out;
position: absolute;
overflow-y: auto;
overflow-x: hidden;
background-color: white;
z-index: 999;
padding-inline-start: 0;
li:hover {
background-color: ghostwhite;
cursor: pointer;
}
li {
padding: 5px;
white-space: nowrap;
list-style-type: none;
text-overflow: ellipsis;
overflow: hidden;
a {
text-decoration: none;
background-color: transparent;
color: black;
}
}
}
&.active > ul {
max-height: 600px;
box-shadow: 1px 1px 3px 0 #ddd;
border: 1px solid#ccc;
}
}
View Compiled
let ghostAPI = new GhostContentAPI({
url: "https://geolytix.ghost.io",
key: "fd7043a685116c5d8768caf7eb",
version: "v3"
});
ghostAPI.posts
.browse({
limit: "all",
fields: ["title", "html", "url"]
})
.then(data => initSearch(data))
.catch(err => {
console.error(err);
});
function initSearch(data) {
const input_drop = document.getElementById("blog-geolytix-search");
input_drop.querySelector("input").addEventListener("keyup", async e => {
input_drop.classList.remove("active");
input_drop.querySelector("ul").innerHTML = "";
const list = data
.map(record => {
var regex = new RegExp(
`(${e.target.value
.split(" ")
.map(term => `(${term})`)
.join("|")})`,
"gim"
);
record.counts = 0;
record.html.replace(regex, function(_, matched) {
matched = matched.toLowerCase();
record.counts++;
});
return record;
})
.filter(record => record.counts > 0)
.sort((a, b) => {
if (a.counts > b.counts) {
return -1;
}
if (a.counts < b.counts) {
return 1;
}
return 0;
});
const items = list.slice(0, 5);
items.forEach(async item => {
const li = document.createElement("li");
li.innerHTML = `<a href="${item.url}" target="_blank">${item.title}</a>`;
input_drop.querySelector("ul").appendChild(li);
});
setTimeout(()=>{
if (!input_drop.querySelector("input").value.length) {
input_drop.classList.remove("active");
input_drop.querySelector("ul").innerHTML = "";
}}, 500);
input_drop.classList.add("active");
});
}
This Pen doesn't use any external CSS resources.