<div id="one" class="url-container">
  <input class="url" type="text" value=''/>
  <style></style>
  <div class="results"></div>
</div>
.url-container {
  position: relative;
  width: 50%;
  overflow: hidden;
  border: 1px solid black;
}
.url-container .result {
  font-family: sans-serif;
  padding: 10px;
}
.url-container .selected {
  background: #efefef;
}
.url-container input {
  padding: 10px;
  width: 100%;
  font-size: 16px;
  font-family: sans-serif;
  color: black;
  background: transparent;
  -webkit-appearance: none;
  outline: none;
  border: none;
}
.url-container:before {
  position: absolute;
  z-index: -1;
  font-size: 16px;
  font-family: sans-serif;
  color: gray;
  left: 0;
  top: 0;
  padding: 10px;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
function SmartInput(el, params) {
  this.el = el;
  this.id = el.attr('id');
  this.input = el.find('input');
  this.input
    .on('change', this.onChange.bind(this))
    .on('input', this.onInput.bind(this))
    .on('keydown', this.onKeyDown.bind(this));
  this.style = el.find('style');
  this.resultList = el.find('.results');
  this.predict = '';
  this.prefix = params.prefix || '$$$';
  this.index = -1;
  this.results = [];
}

SmartInput.prototype = {
  
  beforeRule() {
    return `#${this.id}:before{ content: '${this.predict}' !important; }`;
  },
  
  onKeyDown(e) {
    if (e.which === 13) { // enter
      this.onChange();
    } if (e.which === 39) { // right arrow
      this.input.val(this.predict);
    } else if (this.results.length > 0) {
      if (e.which === 40) { // down arrow
        this.index++;
        if (this.index > this.results.length - 1) this.index = 0;
      } else if (e.which === 38) { // up arrow
        this.index--;
        if (this.index < -1) this.index = this.results.length - 1;
      }
      
      let results = this.resultList 
          .find('.result')
          .removeClass('selected');
      this.predictedVal = null;
      if (this.index !== -1) {
        this.predictedVal = results
          .eq(this.index)
          .addClass('selected')
          .text();
      }
    }
  },
  
  onChange(e) {
    let inputVal = this.predictedVal || this.input.val(),
        key = this.prefix + inputVal;
    if (!localStorage[key]) {
      localStorage[key] = 0;
    } else {
      let val = localStorage[key];
      localStorage[key] = parseFloat(val) + 1;
    }
    console.log('send:', inputVal);
    this.input.val(inputVal);
    this.clearPredictions();
  },
  
  sortResults(a, b) {
    let valA = parseFloat(a.rank),
        valB = parseFloat(b.rank);
    return valB - valA;
  },
  
  clearPredictions() {
    this.index = -1;
    this.resultList.html('');
    this.style.html('');
  },
  
  onInput(e) {
    let results = [], 
        leng = localStorage.length, 
        val = this.input.val().trim(),
        regex = new RegExp('^' + val);
    this.clearPredictions();
    
    if (val.length === 0) { return; }
    
    for (var i = 0; i < leng; i++){
      let key = localStorage.key(i), cleanKey;
      if (key.indexOf(this.prefix) !== -1) {
        cleanKey = key.replace(this.prefix, '');
        if (regex.test(cleanKey)) {
          results.push({key: cleanKey, rank: localStorage[key]});
        }
      }
    }

    if (results.length > 0) {
      this.results = results;
      results.sort(this.sortResults);
      this.predict = results.shift().key;
      this.style.html(this.beforeRule());
      for (let i = 0; i < results.length; i++) {
        if (results[i]) { 
          let r = $('<div class="result">').html(results[i].key);
          r.appendTo(this.resultList);
        }
      }
    } else {
      this.style.html('');
    }
  }
};

let smarty = new SmartInput($('#one'), { prefix: '$$one_' });
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://code.jquery.com/jquery-2.2.4.min.js