Edit in JSFiddle

/*!
 * light-autocomplete v1.0
 * by Lorenzo Dessimoni
 *
 * More info:
 * https://github.com/FunkyOz/light-autocomplete
 *
 * Copyright 20017 Lorenzo Dessimoni
 * Released under the MIT license
 * https://github.com/FunkyOz/light-autocomplete
 *
 * @preserve
 */

(function ($) {
	'use strict';

	var keys = {
		ENTER: 13,
		LEFT: 37,
		UP: 38,
		RIGHT: 39,
		DOWN: 40,
		TAB: 9,
		ESC: 27
	};

	function LightAutocomplete(input, options) {
		this.options = options;
		this.$input = $(input);
		var that = this;
		that.classes = {
			list: 'light-autocomplete-list',
			element: 'light-autocomplete-element',
			container: 'light-autocomplete-container'
		},
		that.selectors ={
			list: '.light-autocomplete-list ul',
			element: '.' + that.classes.element,
			container: '.' + that.classes.container
		},
		that.id = '',
		that.search = '',
		that.last = 0,
		that.firstItem = 1,
		that.data = [],
		that.defaults = {
			minChars: 1,
			heightOfElement: 50,
			visibleElementInList: 5,
			minSize: 6,
			onClick: function(item) {
				that.setItem(item);
			},
			onPressEnter: function(item) {
				that.setItem(item);
			},
			onPressTab: function(item) {
				that.setItem(item);
			},
			onPressEsc: function(item) {
				that.setItem(item);
			}
		};
		that.init();
	};

	$.LightAutocomplete = LightAutocomplete;

	LightAutocomplete.prototype = {
		
		init: function() {
			var that = this;
			that.defaults = $.extend({}, that.defaults, that.options);
			that.defaults.maxHeight = that.defaults.heightOfElement * that.defaults.visibleElementInList;
			if(typeof(that.$input.attr('id')) !== 'undefined' && that.$input.attr('id') !== null) {
				that.id = '#' + that.$input.attr('id');
			} else {
				that.id = 'light-autocomplete-' + Math.ceil(Math.random() * 1000000);
				that.$input.attr('id', that.id);
				that.id = '#' + that.id;
			}
			that.$input.attr('autocomplete', 'off');
			that.createContainer();
			that.insertTemplate();
			that.setKeyDown();
			that.setKeyUp();
			that.setFocus();
		},
		setElementMouseover: function() {
			var that = this;
			var $element = $(that.selectors.element);
			$element.on('mouseover.lightAutocomplete touchstart.lightAutocomplete', function(e) {
				e.preventDefault();
				$(that.selectors.element).removeClass('selected');
				$(this).addClass('selected');
				return false;
			});
		},
		setKeyDown: function() {
			var that = this;
			that.$input.on('keydown.lightAutocomplete', function(e) {
				switch(e.keyCode) {
					case keys.UP:
					case keys.DOWN:
						e.preventDefault();
						return false;
					case keys.ESC:
						e.preventDefault();
						that.ifNotMatchData();
						var item = that.data[0];
						that.defaults.onPressEsc(item);
					break;
					case keys.TAB:
						e.preventDefault();
						that.ifNotMatchData();
						var item = that.data[0];
						that.defaults.onPressTab(item);
					break;
					case keys.ENTER:
						e.preventDefault();
						that.ifNotMatchData();
						var index = parseInt($(that.selectors.element + '.selected').attr('item')) - 1;
						var item = that.data[index];
						that.defaults.onPressEnter(item);
					break;
				}
				that.resetDropDown();
				e.stopImmediatePropagation();
			});
		},
		setKeyUp: function(){
			var that = this;
			that.$input.on('keyup.lightAutocomplete', function(e) {
				switch(e.keyCode) {
					case keys.ESC:
					case keys.TAB:
					case keys.ENTER:
					case keys.LEFT:
					case keys.RIGHT:
						e.preventDefault();
						return false;
					break;
					case keys.UP:
						e.preventDefault();
						that.moveUp();
						return false;
					break;
					case keys.DOWN:
						e.preventDefault();
						that.moveDown();
						return false;
					break;
					default:
						that.firstItem = 1;
					break;
				}
				that.showTemplate();
				that.search = that.$input.val().toLowerCase();
				if(that.search.length >= that.defaults.minChars){
					that.defaults.sourceData(that.search, function(data) {
						if(data.lenght > 0) that.data = [];
						that.createDropDown(data);
					});
				}
			});
		},
		moveDown: function() {
			var that = this;
			var item = parseInt($(that.selectors.element + '.selected').attr('item'));
			$(that.selectors.element).removeClass('selected');
			if(item < that.last) {
				$(that.selectors.element + '[item="' + (item + 1) + '"]').addClass('selected');
			} else {
				$(that.selectors.element + '[item="' + that.last + '"]').addClass('selected');
			}
			if(item == (that.firstItem + that.defaults.visibleElementInList - 1) && item != that.last) {
				$(that.selectors.list, that.selectors.container).animate({
					scrollTop: '+=' + that.defaults.heightOfElement
				}, 50);
				that.firstItem++;
			}
		},
		moveUp: function() {
			var that = this;
			var item = parseInt($(that.selectors.element + '.selected').attr('item'));
			$(that.selectors.element).removeClass('selected');
			if(item > 1) {
				$(that.selectors.element + '[item="' + (item - 1) + '"]').addClass('selected');
			} else {
				$(that.selectors.element + '[item="' + 1 + '"]').addClass('selected');
			}
			if(item == that.firstItem && item != 1) {
				$(that.selectors.list, that.selectors.container).animate({
					scrollTop: '-=' + that.defaults.heightOfElement
				}, 50);
				that.firstItem--;
			}
		},
		createDropDown: function(data) {
			var that = this;
			var index = 0;
			data.forEach(function(element, i) {
				if(that.defaults.minSize !== false && index >= that.defaults.minSize) {
					return false;
				}
				if(element.label.toLowerCase().indexOf(that.search) > -1) {
					that.data[index] = element;
					that.last = ++index;
					$(that.selectors.list, that.selectors.container, that.$input.parent()).append(that.createTempleteItem(element, index));
				}
			});
			that.setClick();
			that.setElementMouseover();
		},
		setFocus: function() {
			var that = this;
			$(document).on('click',function(e) {
				var $container = $(that.selectors.container);
				if (!$container.is(e.target) && !that.$input.is(e.target)) {
					$(that.selectors.list, $container).hide();
				} else {
					if(that.$input.is(e.target)) $(that.selectors.list ,$container).show();
				}
			});
		},
		setItem: function(item) {
			var that = this;
			if (typeof item !== 'undefined') {
				that.$input.val(item.label);
			}
		},
		setClick: function() {
			var that = this;
			var $element = $(that.selectors.element);
			$element.on('click.lightAutocomplete tap.lightAutocomplete', function() {
				that.ifNotMatchData();
				var index = parseInt($(this).attr('item')) - 1;
				var item = that.data[index];
				that.defaults.onClick(item);
				that.resetDropDown();
			});
		},
		resetDropDown: function() {
			var that = this;
			that.data = [];
			$(that.selectors.list, that.selectors.container).parent().remove();
			that.insertTemplate();
		},
		insertTemplate: function() {
			var that = this;
			$(that.createTemplateList()).insertAfter(that.id);
		},
		ifNotMatchData: function() {
			var that = this;
			if(that.$input.val() == '') {
				that.data = [];
			}
			if(!$(that.selectors.list + ' li', that.selectors.container).length) {
				that.data = [];
			}
		},
		showTemplate: function() {
			var that = this;
			$(that.selectors.list, that.selectors.container).parent().show();
			$(that.selectors.list, that.selectors.container).html('');
		},
		createContainer: function() {
			var that = this;
			that.$input.wrap('<div class="' + that.classes.container + '"></div>');
		},
		createTemplateList: function() {
			var that = this;
			return '<div class="' + that.classes.list + '" style="display:none;"><ul style="overflow-y: scroll; max-height: ' + that.defaults.maxHeight + 'px;"></ul></div>'
		},
		createTempleteItem: function(item, index) {
			var that = this;
			var seleceted = '';
			if(index == 1) seleceted = ' selected';
			return  '<li><div item="' + index + '" class="' + that.classes.element + ' ' + seleceted + '" style="max-height: ' + that.defaults.heightOfElement + 'px;">' + item.label + '</div></li>';
		}
	}
	$.fn.lightAutocomplete = function (options, args) {
        var dataKey = 'lightAutocomplete';
        if (!arguments.length) {
            return this.first().data(dataKey);
        }
        return this.each(function () {
            var inputElement = $(this),
				instance = inputElement.data(dataKey);
            if (typeof options === 'string') {
                if (instance && typeof instance[options] === 'function') {
                    instance[options](args);
                }
            } else {
                if (instance && instance.dispose) {
                    instance.dispose();
                }
                instance = new LightAutocomplete(this, options);
                inputElement.data(dataKey, instance);
            }
        });
    };
})(jQuery);


var data = [
	{ label: 'Tokyo', value: 'Tokyo' },
	{ label: 'Milano', value: 'Milano' },
	{ label: 'Roma', value: 'Roma' },
	{ label: 'Napoli', value: 'Napoli' },
	{ label: 'Venezia', value: 'Venezia' },
	{ label: 'Bologna', value: 'Bologna' },
	{ label: 'Genova', value: 'Genova' },
	{ label: 'Firenze', value: 'Firenze' },
];

var options = {
    sourceData: function(search, success) {
        dataResponse = [];
        data.forEach(function(el, i) {
            dataResponse.push({
                label: i +  ' - ' + el.label,
                value: i +  ' - ' + el.value
            });
        });
        success(dataResponse);
    },
    minChar: 3
    
};

$('#light-autocomplete').lightAutocomplete(options);

              
ex.<input type="text" class="form-control" id="light-autocomplete" autocomplete="off" placeholder="ローマ字で都市名を入力">