(function($) { $.fn.selector2 = function(items, options) { if (this.length == 0) return; this.each(function() { var labelElement = $(this); var valueField = $('input', labelElement.parent()); var currentIndex = -1; var defaults = { selectCallback: null }; if (options == undefined) options = {}; var opts = $.extend({}, defaults, options); labelElement.on('click', function() { var currentValue = valueField.val(); var val, html = '
'; for (var i = 0; i < items.length; i++) { html += '
'; } html += '
'; var helper = $(html).appendTo('body'); var offset = $(this).offset(); helper.css('top', Math.max(0, offset.top - currentIndex * 22 - 1) + 'px'); helper.css('left', (offset.left - 7) + 'px'); helper.on('click', '> div', function() { var el = $(this); var val = el.data('value'); var idx = el.data('index'); valueField.val(val); labelElement.html(items[idx].label); if (opts.selectCallback) opts.selectCallback.call(labelElement, val); helper.remove(); $(document).off('.selector2'); }) .on('mouseenter', '> div', function() { var el = $(this); el.addClass('hov').siblings().removeClass('hov'); currentIndex = el.data('index'); }); $(document).on('click.selector2', function(e) { if (!$(e.target).is(helper)) helper.remove(); $(document).off('.selector2'); }) .on('keydown.selector2', function(e) { if (e.which == 40 || e.which == 38) { e.preventDefault(); $('> div', helper).removeClass('hov'); if (e.which == 40 && ++currentIndex == items.length) currentIndex = 0; else if (e.which == 38 && --currentIndex < 0) currentIndex = items.length - 1; $('div[data-index="' + currentIndex + '"]', helper).addClass('hov'); } else if ((e.which == 13 || e.which == 32) && currentIndex != -1) { e.preventDefault(); $('div[data-index="' + currentIndex + '"]', helper).trigger('click'); } else if (e.which == 27 || e.which == 8) { e.preventDefault(); helper.remove(); $(document).off('.selector2'); } }); helper.show(); return false; }); }); return this; }; })(jQuery);