Vanilla autocomplete

by Alon Rotem

HTML

<p>
  Select a continent
</p>
<div>
  <input id="inputtext" type="text"><br/>
  <select id="sel" size=5>
    <option value="europe">Europe</option>
    <option value="asia">Asia</option>
    <option value="africa">Africa</option>
    <option value="america">America</option>
    <option value="australia">Australia</option>
     <option value="antarctica">Antarctica</option>
  </select>
</div>

CSS

input
{
  outline: none;
}

select
{
  width: 400px;
  display: none;
  outline: none;
}

JavaScript

var inp = document.getElementById("inputtext");
var sel = document.getElementById("sel");
inp.focus();

inp
	.addEventListener("input", function(e){
  	var value  = e.target.value.toLowerCase().trim();
  	console.log(e.target.value);
    var optionSelected = false;
    Array.from(sel.options).forEach(function(opt){
    	var visible = (opt.text.toLowerCase().indexOf(value) >= 0);
    	opt.style.display = (visible)? "block": "none";
      if(visible)
      {
        if(!optionSelected)
        {
          optionSelected = true;
          opt.setAttribute("selected", "selected");
          opt.setAttribute("data-first", true);
        }
        else
        {
        	opt.setAttribute("data-first", false);
        }
      }
    });
    sel.style.display = (value && optionSelected)? "block": "none";
  });
  
inp
	.addEventListener('keydown', function (e) {
    e = e || window.event;
    var keyCode = e.keyCode || e.which;
		console.log("key " + keyCode + ", position:" + inp.selectionStart);
    if(keyCode=='40'){ //Arrow down
    		sel.focus();
        e.preventDefault();
        return false;
    }        
}, false);

sel
	.addEventListener('keydown', function (e) {
    e = e || window.event;
    var keyCode = e.keyCode || e.which;
    if(keyCode == 13 && sel.selectedIndex >= 0) //Enter
    {
    	inp.value = sel.options[sel.selectedIndex].text;
      sel.style.display = "none";
      inp.focus();
    }
    else if (keyCode == 38) //key up
    {
    	if(sel[sel.selectedIndex].getAttribute("data-first") == "true")
      {
      	inp.focus();
      }
    }
  });
  
  sel
	.addEventListener('click', function (e) {
   if(sel.selectedIndex >= 0) //Enter
    {
    	inp.value = sel.options[sel.selectedIndex].text;
      sel.style.display = "none";
      inp.focus();
    }
  });