/* global jQuery, Bloodhound */ (function (jQuery, Bloodhound) { 'use strict'; var $template = jQuery('
  • '); jQuery.fn.extend({ auto_select: function (typeaheadOptions, engineOptions) { jQuery(this).each(function () { var $container = jQuery(this), $input = $container.find('div input:visible'); setup($container, $input, typeaheadOptions, engineOptions); $input .off('typeahead:select') .off('typeahead:change') .on('typeahead:select typeahead:autocomplete', function onSelect(_event, suggestion) { appendAndFocusOnSelection($container, $input, suggestion); }) .on('keypress', ignoreTabAndEnter); $container .off('click.auto_select') .on('click.auto_select', 'a', function onRemove(_event) { jQuery(this).parent().remove(); disableTypeaheadOnSingleSelection($container, $input); }); }); } }); function setup($container, $input, typeaheadOptions, engineOptions) { moveAttributesIntoDataFor($input); recreateTypeahead($input, typeaheadOptions, engineOptions, $container.data()); disableTypeaheadOnSingleSelection($container, $input); } function moveAttributesIntoDataFor($input) { $input.data('name', $input.attr('name')); $input.data('multiple', $input.attr('multiple')); $input.removeAttr('name').removeAttr('multiple'); } function recreateTypeahead($input, typeaheadOptions, engineOptions, containerOptions) { var options = jQuery.extend({ highlight: true, hint: true, minLength: 1 }, typeaheadOptions), sourceOptions = { name: containerOptions.source, display: 'label', source: new Bloodhound( jQuery.extend({ remote: { url: containerOptions.url, wildcard: containerOptions.wildcard }, queryTokenizer: Bloodhound.tokenizers.whitespace, datumTokenizer: Bloodhound.tokenizers.whitespace }, engineOptions) ) }; $input.typeahead('destroy') $input.typeahead(options, sourceOptions); } function disableTypeaheadOnSingleSelection($container, $input) { var $anchors = $container.find('a'), $count = $container.find('.auto_select__count span'), countOfAnchors = $anchors.length, isMultiple = $input.data('multiple'); $input.prop('disabled', !isMultiple && countOfAnchors === 1); $count.text(countOfAnchors); } function appendAndFocusOnSelection($container, $input, suggestion) { var $anchor, $existing = $container.find('input[value=' + suggestion.id + ']'), isMultiple = $input.data('multiple'), inputName = $input.data('name'); if ($existing.length) { $anchor = $existing.next(); } else { var $newItem = $template.clone(), $itemInput = $newItem.find('input'), $list = $container.find('ul'); $itemInput.attr('name', inputName).val(suggestion.id); $list.append($newItem); $anchor = $newItem.find('a').text(suggestion.label); disableTypeaheadOnSingleSelection($container, $input); } if (isMultiple) { $anchor.focus(); } $input.typeahead('val', ''); } function ignoreTabAndEnter(event) { var keyCode = event.keyCode || event.which; if (keyCode === 13 || keyCode === 9) { return false; } } })(jQuery, Bloodhound);