$(function() { $.fn.autocomplete = function(option) { return this.each(function() { this.timer = null; this.items = new Array(); $.extend(this, option); $(this).attr('autocomplete', 'off'); // Focus $(this).on('focus', function() { this.request(); }); // Blur $(this).on('blur', function() { setTimeout(function(object) { object.hide(); }, 200, this); }); // Keydown $(this).on('keydown', function(event) { switch(event.keyCode) { case 27: // escape this.hide(); break; default: this.request(); break; } }); // Click this.click = function(event) { event.preventDefault(); let value = $(event.target).parent().attr('data-value'); if (value && this.items[value]) { this.select(this.items[value]); } } // Show this.show = function() { var pos = $(this).position(); $(this).siblings('ul.dropdown-menu').css({ top: pos.top + $(this).outerHeight(), left: pos.left }); $(this).siblings('ul.dropdown-menu').show(); } // Hide this.hide = function() { $(this).siblings('ul.dropdown-menu').hide(); } // Request this.request = function() { clearTimeout(this.timer); this.timer = setTimeout(function(object) { object.source($(object).val(), $.proxy(object.response, object)); }, 200, this); } // Response this.response = function(json) { let hasFocus = $(this).is(':focus'); if (!hasFocus) return; var html = ''; if (json.length) { for (var i = 0; i < json.length; i++) { this.items[json[i]['value']] = json[i]; } for (var i = 0; i < json.length; i++) { if (!json[i]['category']) { html += '
  • ' + json[i]['label'] + '
  • '; } } // Get all the ones with a categories var category = new Array(); for (var i = 0; i < json.length; i++) { if (json[i]['category']) { if (!category[json[i]['category']]) { category[json[i]['category']] = new Array(); category[json[i]['category']]['name'] = json[i]['category']; category[json[i]['category']]['item'] = new Array(); } category[json[i]['category']]['item'].push(json[i]); } } for (var i in category) { html += ''; for (j = 0; j < category[i]['item'].length; j++) { html += '
  •    ' + category[i]['item'][j]['label'] + '
  • '; } } } if (html) { this.show(); } else { this.hide(); } $(this).siblings('ul.dropdown-menu').html(html); } $(this).after(''); $(this).siblings('ul.dropdown-menu').delegate('a', 'click', $.proxy(this.click, this)); }); } });