/* * easy-autocomplete * jQuery plugin for autocompletion * * @author Łukasz Pawełczak (http://github.com/pawelczak) * @version 1.4.0 * Copyright License: */ /* * EasyAutocomplete - Configuration */ (function ($) { var EasyAutocomplete = (function (scope) { scope.Configuration = function Configuration(options) { var defaults = { data: 'list-required', url: 'list-required', dataType: 'json', listLocation: function (data) { return data; }, xmlElementName: '', getValue: function (element) { return element; }, autocompleteOff: true, placeholder: false, ajaxCallback: function () { }, matchResponseProperty: false, list: { sort: { enabled: false, method: function (a, b) { a = defaults.getValue(a); b = defaults.getValue(b); if (a < b) { return -1; } if (a > b) { return 1; } return 0; } }, maxNumberOfElements: 6, hideOnEmptyPhrase: true, match: { enabled: false, caseSensitive: false, method: function (element, phrase) { return element.search(phrase) > -1; } }, showAnimation: { type: 'normal', //normal|slide|fade time: 400, callback: function () { } }, hideAnimation: { type: 'normal', time: 400, callback: function () { } }, /* Events */ onClickEvent: function () { }, onSelectItemEvent: function () { }, onLoadEvent: function () { }, onChooseEvent: function () { }, onKeyEnterEvent: function () { }, onMouseOverEvent: function () { }, onMouseOutEvent: function () { }, onShowListEvent: function () { }, onHideListEvent: function () { } }, highlightPhrase: true, theme: '', cssClasses: '', minCharNumber: 0, requestDelay: 0, adjustWidth: true, ajaxSettings: {}, preparePostData: function (data, inputPhrase) { return data; }, loggerEnabled: true, template: '', categoriesAssigned: false, categories: [{ maxNumberOfElements: 4 }] }; var externalObjects = ['ajaxSettings', 'template']; this.get = function (propertyName) { return defaults[propertyName]; }; this.equals = function (name, value) { if (isAssigned(name)) { if (defaults[name] === value) { return true; } } return false; }; this.checkDataUrlProperties = function () { return !(defaults.url === 'list-required' && defaults.data === 'list-required'); }; this.checkRequiredProperties = function () { for (var propertyName in defaults) { if (defaults[propertyName] === 'required') { logger.error('Option ' + propertyName + ' must be defined'); return false; } } return true; }; this.printPropertiesThatDoesntExist = function (consol, optionsToCheck) { printPropertiesThatDoesntExist(consol, optionsToCheck); }; prepareDefaults(); mergeOptions(); if (defaults.loggerEnabled === true) { printPropertiesThatDoesntExist(console, options); } addAjaxSettings(); processAfterMerge(); function prepareDefaults() { if (options.dataType === 'xml') { if (!options.getValue) { options.getValue = function (element) { return $(element).text(); }; } if (!options.list) { options.list = {}; } if (!options.list.sort) { options.list.sort = {}; } options.list.sort.method = function (a, b) { a = options.getValue(a); b = options.getValue(b); if (a < b) { return -1; } if (a > b) { return 1; } return 0; }; if (!options.list.match) { options.list.match = {}; } options.list.match.method = function (element, phrase) { return element.search(phrase) > -1; }; } if (options.categories !== undefined && options.categories instanceof Array) { var categories = []; for (var i = 0, length = options.categories.length; i < length; i += 1) { var category = options.categories[i]; for (var property in defaults.categories[0]) { if (category[property] === undefined) { category[property] = defaults.categories[0][property]; } } categories.push(category); } options.categories = categories; } } function mergeOptions() { defaults = mergeObjects(defaults, options); function mergeObjects(source, target) { var mergedObject = source || {}; for (var propertyName in source) { if (target[propertyName] !== undefined && target[propertyName] !== null) { if (typeof target[propertyName] !== 'object' || target[propertyName] instanceof Array) { mergedObject[propertyName] = target[propertyName]; } else { mergeObjects(source[propertyName], target[propertyName]); } } } /* If data is an object */ if (target.data !== undefined && target.data !== null && typeof target.data === 'object') { mergedObject.data = target.data; } return mergedObject; } } function processAfterMerge() { if (defaults.url !== 'list-required' && typeof defaults.url !== 'function') { var defaultUrl = defaults.url; defaults.url = function () { return defaultUrl; }; } if (defaults.ajaxSettings.url !== undefined && typeof defaults.ajaxSettings.url !== 'function') { var defaultUrl = defaults.ajaxSettings.url; defaults.ajaxSettings.url = function () { return defaultUrl; }; } if (typeof defaults.listLocation === 'string') { var defaultlistLocation = defaults.listLocation; if (defaults.dataType.toUpperCase() === 'XML') { defaults.listLocation = function (data) { return $(data).find(defaultlistLocation); }; } else { defaults.listLocation = function (data) { return data[defaultlistLocation]; }; } } if (typeof defaults.getValue === 'string') { var defaultsGetValue = defaults.getValue; defaults.getValue = function (element) { return element[defaultsGetValue]; }; } if (options.categories !== undefined) { defaults.categoriesAssigned = true; } } function addAjaxSettings() { if (options.ajaxSettings !== undefined && typeof options.ajaxSettings === 'object') { defaults.ajaxSettings = options.ajaxSettings; } else { defaults.ajaxSettings = {}; } } function isAssigned(name) { return defaults[name] !== undefined && defaults[name] !== null; } function printPropertiesThatDoesntExist(consol, optionsToCheck) { checkPropertiesIfExist(defaults, optionsToCheck); function checkPropertiesIfExist(source, target) { for (var property in target) { if (source[property] === undefined) { consol.log('Property \'' + property + '\' does not exist in EasyAutocomplete options API.'); } if (typeof source[property] === 'object' && jQuery.inArray(property, externalObjects) === -1) { checkPropertiesIfExist(source[property], target[property]); } } } } }; return scope; })(EasyAutocomplete || {}); /* * EasyAutocomplete - Logger */ var EasyAutocomplete = (function (scope) { scope.Logger = function Logger() { this.error = function (message) { console.log('ERROR: ' + message); }; this.warning = function (message) { console.log('WARNING: ' + message); }; }; return scope; })(EasyAutocomplete || {}); /* * EasyAutocomplete - Constants */ var EasyAutocomplete = (function (scope) { scope.Constants = function Constants() { var constants = { CONTAINER_CLASS: 'easy-autocomplete-container', CONTAINER_ID: 'eac-container-', WRAPPER_CSS_CLASS: 'easy-autocomplete' }; this.getValue = function (propertyName) { return constants[propertyName]; }; }; return scope; })(EasyAutocomplete || {}); /* * EasyAutocomplete - ListBuilderService * * @author Łukasz Pawełczak * */ var EasyAutocomplete = (function (scope) { scope.ListBuilderService = function ListBuilderService(configuration, proccessResponseData) { this.init = function (data) { var listBuilder = [], builder = {}; builder.data = configuration.get('listLocation')(data); builder.getValue = configuration.get('getValue'); builder.maxListSize = configuration.get('list').maxNumberOfElements; listBuilder.push(builder); return listBuilder; }; this.updateCategories = function (listBuilder, data) { if (configuration.get('categoriesAssigned')) { listBuilder = []; for (var i = 0; i < configuration.get("categories").length; i += 1) { var builder = convertToListBuilder(configuration.get('categories')[i], data); listBuilder.push(builder); } } return listBuilder; }; this.convertXml = function (listBuilder) { if (configuration.get('dataType').toUpperCase() === 'XML') { for (var i = 0; i < listBuilder.length; i += 1) { listBuilder[i].data = convertXmlToList(listBuilder[i]); } } return listBuilder; }; this.processData = function (listBuilder, inputPhrase) { for (var i = 0, length = listBuilder.length; i < length; i += 1) { listBuilder[i].data = proccessResponseData(configuration, listBuilder[i], inputPhrase); } return listBuilder; }; this.checkIfDataExists = function (listBuilders) { for (var i = 0, length = listBuilders.length; i < length; i += 1) { if (listBuilders[i].data !== undefined && listBuilders[i].data instanceof Array) { if (listBuilders[i].data.length > 0) { return true; } } } return false; }; function convertToListBuilder(category, data) { var builder = {}; if (configuration.get('dataType').toUpperCase() === 'XML') { builder = convertXmlToListBuilder(); } else { builder = convertDataToListBuilder(); } if (category.header !== undefined) { builder.header = category.header; } if (category.maxNumberOfElements !== undefined) { builder.maxNumberOfElements = category.maxNumberOfElements; } if (configuration.get('list').maxNumberOfElements !== undefined) { builder.maxListSize = configuration.get('list').maxNumberOfElements; } if (category.getValue !== undefined) { if (typeof category.getValue === 'string') { var defaultsGetValue = category.getValue; builder.getValue = function (element) { return element[defaultsGetValue]; }; } else if (typeof category.getValue === 'function') { builder.getValue = category.getValue; } } else { builder.getValue = configuration.get('getValue'); } return builder; function convertXmlToListBuilder() { var builder = {}, listLocation; if (category.xmlElementName !== undefined) { builder.xmlElementName = category.xmlElementName; } if (category.listLocation !== undefined) { listLocation = category.listLocation; } else if (configuration.get('listLocation') !== undefined) { listLocation = configuration.get('listLocation'); } if (listLocation !== undefined) { if (typeof listLocation === 'string') { builder.data = $(data).find(listLocation); } else if (typeof listLocation === 'function') { builder.data = listLocation(data); } } else { builder.data = data; } return builder; } function convertDataToListBuilder() { var builder = {}; if (category.listLocation !== undefined) { if (typeof category.listLocation === 'string') { builder.data = data[category.listLocation]; } else if (typeof category.listLocation === 'function') { builder.data = category.listLocation(data); } } else { builder.data = data; } return builder; } } function convertXmlToList(builder) { var simpleList = []; if (builder.xmlElementName === undefined) { builder.xmlElementName = configuration.get('xmlElementName'); } $(builder.data).find(builder.xmlElementName).each(function () { simpleList.push(this); }); return simpleList; } }; return scope; })(EasyAutocomplete || {}); /* * EasyAutocomplete - Data proccess module * * Process list to display: * - sort * - decrease number to specific number * - show only matching list * */ var EasyAutocomplete = (function (scope) { scope.proccess = function DataProcessor(config, listBuilder, phrase) { scope.proccess.match = match; var list = listBuilder.data, inputPhrase = phrase; // TODO REFACTOR list = findMatch(list, inputPhrase); list = reduceElementsInList(list); list = sort(list); return list; function findMatch(list, phrase) { var preparedList = [], value = ''; if (config.get('list').match.enabled) { for (var i = 0, length = list.length; i < length; i += 1) { value = config.get('getValue')(list[i]); if (match(value, phrase)) { preparedList.push(list[i]); } } } else { preparedList = list; } return preparedList; } function match(value, phrase) { if (!config.get('list').match.caseSensitive) { if (typeof value === 'string') { value = value.toLowerCase(); } phrase = phrase.toLowerCase(); } return (config.get('list').match.method(value, phrase)); } function reduceElementsInList(list) { if (listBuilder.maxNumberOfElements !== undefined && list.length > listBuilder.maxNumberOfElements) { list = list.slice(0, listBuilder.maxNumberOfElements); } return list; } function sort(list) { if (config.get('list').sort.enabled) { list.sort(config.get('list').sort.method); } return list; } }; return scope; })(EasyAutocomplete || {}); /* * EasyAutocomplete - Template * * * */ var EasyAutocomplete = (function (scope) { scope.Template = function Template(options) { var genericTemplates = { basic: { type: 'basic', method: function (element) { return element; }, cssClass: '' }, description: { type: 'description', fields: { description: 'description' }, method: function (element) { return element + ' - description'; }, cssClass: 'eac-description' }, iconLeft: { type: 'iconLeft', fields: { icon: '' }, method: function (element) { return element; }, cssClass: 'eac-icon-left' }, iconRight: { type: 'iconRight', fields: { iconSrc: '' }, method: function (element) { return element; }, cssClass: 'eac-icon-right' }, links: { type: 'links', fields: { link: '' }, method: function (element) { return element; }, cssClass: '' }, custom: { type: 'custom', method: function () { }, cssClass: '' } }, /* * Converts method with {{text}} to function */ convertTemplateToMethod = function (template) { var _fields = template.fields, buildMethod; if (template.type === 'description') { buildMethod = genericTemplates.description.method; if (typeof _fields.description === 'string') { buildMethod = function (elementValue, element) { return elementValue + ' - <span>' + element[_fields.description] + '</span>'; }; } else if (typeof _fields.description === 'function') { buildMethod = function (elementValue, element) { return elementValue + ' - <span>' + _fields.description(element) + '</span>'; }; } return buildMethod; } if (template.type === 'iconRight') { if (typeof _fields.iconSrc === 'string') { buildMethod = function (elementValue, element) { return elementValue + '<img class=\'eac-icon\' src=\'' + element[_fields.iconSrc] + '\' />'; }; } else if (typeof _fields.iconSrc === 'function') { buildMethod = function (elementValue, element) { return elementValue + '<img class=\'eac-icon\' src=\'' + _fields.iconSrc(element) + '\' />'; }; } return buildMethod; } if (template.type === 'iconLeft') { if (typeof _fields.iconSrc === 'string') { buildMethod = function (elementValue, element) { return '<img class=\'eac-icon\' src=\'' + element[_fields.iconSrc] + '\' />' + elementValue; }; } else if (typeof _fields.iconSrc === 'function') { buildMethod = function (elementValue, element) { return '<img class=\'eac-icon\' src=\'' + _fields.iconSrc(element) + '\' />' + elementValue; }; } return buildMethod; } if (template.type === 'links') { if (typeof _fields.link === 'string') { buildMethod = function (elementValue, element) { return '<a href=\'' + element[_fields.link] + '\' >' + elementValue + '</a>'; }; } else if (typeof _fields.link === 'function') { buildMethod = function (elementValue, element) { return '<a href=\'' + _fields.link(element) + '\' >' + elementValue + '</a>'; }; } return buildMethod; } if (template.type === 'custom') { return template.method; } return genericTemplates.basic.method; }, prepareBuildMethod = function (options) { if (!options || !options.type) { return genericTemplates.basic.method; } if (options.type && genericTemplates[options.type]) { return convertTemplateToMethod(options); } else { return genericTemplates.basic.method; } }, templateClass = function (options) { var emptyStringFunction = function () { return ''; }; if (!options || !options.type) { return emptyStringFunction; } if (options.type && genericTemplates[options.type]) { return (function () { var _cssClass = genericTemplates[options.type].cssClass; return function () { return _cssClass; }; })(); } else { return emptyStringFunction; } }; this.getTemplateClass = templateClass(options); this.build = prepareBuildMethod(options); }; return scope; })(EasyAutocomplete || {}); /* * EasyAutocomplete - jQuery plugin for autocompletion * */ var EasyAutocomplete = (function (scope) { scope.main = function Core($input, options) { var module = { name: 'EasyAutocomplete', shortcut: 'eac' }; var consts = new scope.Constants(), config = new scope.Configuration(options), logger = new scope.Logger(), template = new scope.Template(options.template), listBuilderService = new scope.ListBuilderService(config, scope.proccess), checkParam = config.equals, $field = $input, $container = '', elementsList = [], selectedElement = -1, requestDelayTimeoutId; scope.consts = consts; this.getConstants = function () { return consts; }; this.getConfiguration = function () { return config; }; this.getContainer = function () { return $container; }; this.getSelectedItemIndex = function () { return selectedElement; }; this.getItems = function () { return elementsList; }; this.getItemData = function (index) { if (elementsList.length < index || elementsList[index] === undefined) { return -1; } else { return elementsList[index]; } }; this.getSelectedItemData = function () { return this.getItemData(selectedElement); }; this.build = function () { prepareField(); }; this.init = function () { init(); }; function init() { if ($field.length === 0) { logger.error('Input field doesn\'t exist.'); return; } if (!config.checkDataUrlProperties()) { logger.error('One of options variables \'data\' or \'url\' must be defined.'); return; } if (!config.checkRequiredProperties()) { logger.error('Will not work without mentioned properties.'); return; } prepareField(); bindEvents(); } function prepareField() { if ($field.parent().hasClass(consts.getValue('WRAPPER_CSS_CLASS'))) { removeContainer(); removeWrapper(); } createWrapper(); createContainer(); $container = $('#' + getContainerId()); if (config.get('placeholder')) { $field.attr('placeholder', config.get('placeholder')); } function createWrapper() { var $wrapper = $('<div>'), classes = consts.getValue('WRAPPER_CSS_CLASS'); if (config.get('theme') && config.get('theme') !== '') { classes += ' eac-' + config.get('theme'); } if (config.get('cssClasses') && config.get('cssClasses') !== '') { classes += ' ' + config.get('cssClasses'); } if (template.getTemplateClass() !== '') { classes += ' ' + template.getTemplateClass(); } $wrapper .addClass(classes); $field.wrap($wrapper); if (config.get('adjustWidth') === true) { adjustWrapperWidth(); } } function adjustWrapperWidth() { var fieldWidth = $field.outerWidth(); $field.parent().css('width', fieldWidth); } function removeWrapper() { $field.unwrap(); } function createContainer() { var $elements_container = $('<div>').addClass(consts.getValue('CONTAINER_CLASS')); $elements_container .attr('id', getContainerId()) .prepend($('<ul>')); (function () { $elements_container /* List show animation */ .on('show.eac', function () { if (!$field.is(':focus')) {return} switch(config.get('list').showAnimation.type) { case 'slide': var animationTime = config.get('list').showAnimation.time, callback = config.get('list').showAnimation.callback; $elements_container.find('ul').slideDown(animationTime, callback); break; case 'fade': var animationTime = config.get('list').showAnimation.time, callback = config.get('list').showAnimation.callback; $elements_container.find('ul').fadeIn(animationTime), callback; break; default: $elements_container.find('ul').show(); break; } config.get('list').onShowListEvent(); }) /* List hide animation */ .on('hide.eac', function () { switch (config.get('list').hideAnimation.type) { case 'slide': var animationTime = config.get('list').hideAnimation.time, callback = config.get('list').hideAnimation.callback; $elements_container.find('ul').slideUp(animationTime, callback); break; case 'fade': var animationTime = config.get('list').hideAnimation.time, callback = config.get('list').hideAnimation.callback; $elements_container.find('ul').fadeOut(animationTime, callback); break; default: $elements_container.find('ul').hide(); break; } config.get('list').onHideListEvent(); }) .on('selectElement.eac', function () { $elements_container.find('ul li').removeClass('selected'); $elements_container.find('ul li').eq(selectedElement).addClass('selected'); config.get('list').onSelectItemEvent(); }) .on('loadElements.eac', function (event, listBuilders, phrase) { var $item = '', $listContainer = $elements_container.find('ul'); $listContainer .empty() .detach(); elementsList = []; var counter = 0; for (var builderIndex = 0, listBuildersLength = listBuilders.length; builderIndex < listBuildersLength; builderIndex += 1) { var listData = listBuilders[builderIndex].data; if (listData.length === 0) { continue; } if (listBuilders[builderIndex].header !== undefined && listBuilders[builderIndex].header.length > 0) { $listContainer.append('<div class=\'eac-category\' >' + listBuilders[builderIndex].header + '</div>'); } for (var i = 0, listDataLength = listData.length; i < listDataLength && counter < listBuilders[builderIndex].maxListSize; i += 1) { $item = $('<li><div class=\'eac-item\'></div></li>'); (function () { var j = i, itemCounter = counter, elementsValue = listBuilders[builderIndex].getValue(listData[j]); $item.find(' > div') .on('click', function () { $field.val(elementsValue).trigger('change'); selectedElement = itemCounter; selectElement(itemCounter); config.get('list').onClickEvent(); config.get('list').onChooseEvent(); }) .mouseover(function () { selectedElement = itemCounter; selectElement(itemCounter); config.get('list').onMouseOverEvent(); }) .mouseout(function () { config.get('list').onMouseOutEvent(); }) .html(template.build(highlight(elementsValue, phrase), listData[j])); })(); $listContainer.append($item); elementsList.push(listData[i]); counter += 1; } } $elements_container.append($listContainer); config.get('list').onLoadEvent(); }); })(); $field.after($elements_container); } function removeContainer() { $field.next('.' + consts.getValue('CONTAINER_CLASS')).remove(); } function highlight(string, phrase) { if (config.get('highlightPhrase') && phrase !== '') { return highlightPhrase(string, phrase); } else { return string; } } function escapeRegExp(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); } function highlightPhrase(string, phrase) { var escapedPhrase = escapeRegExp(phrase); return (string + '').replace(new RegExp('(' + escapedPhrase + ')', 'gi'), '<b>$1</b>'); } } function getContainerId() { var elementId = $field.attr('id'); elementId = consts.getValue('CONTAINER_ID') + elementId; return elementId; } function bindEvents() { bindAllEvents(); function bindAllEvents() { if (checkParam('autocompleteOff', true)) { removeAutocomplete(); } bindFocusOut(); bindKeyup(); bindKeydown(); bindKeypress(); bindFocus(); bindBlur(); } function bindFocusOut() { $field.focusout(function () { var fieldValue = $field.val(), phrase; if (!config.get('list').match.caseSensitive) { fieldValue = fieldValue.toLowerCase(); } for (var i = 0, length = elementsList.length; i < length; i += 1) { phrase = config.get('getValue')(elementsList[i]); if (!config.get('list').match.caseSensitive) { phrase = phrase.toLowerCase(); } if (phrase === fieldValue) { selectedElement = i; selectElement(selectedElement); return; } } }); } function bindKeyup() { $field .off('keyup') .keyup(function (event) { switch (event.keyCode) { case 27: hideContainer(); loseFieldFocus(); break; case 38: event.preventDefault(); if (elementsList.length > 0 && selectedElement > 0) { selectedElement -= 1; $field.val(config.get('getValue')(elementsList[selectedElement])); selectElement(selectedElement); } break; case 40: event.preventDefault(); if (elementsList.length > 0 && selectedElement < elementsList.length - 1) { selectedElement += 1; $field.val(config.get('getValue')(elementsList[selectedElement])); selectElement(selectedElement); } break; default: if (event.keyCode > 40 || event.keyCode === 8 || event.keyCode === 0) { var inputPhrase = $field.val(); if (!(config.get('list').hideOnEmptyPhrase === true && event.keyCode === 8 && inputPhrase === '')) { if (config.get('requestDelay') > 0) { if (requestDelayTimeoutId !== undefined) { clearTimeout(requestDelayTimeoutId); } requestDelayTimeoutId = setTimeout(function () { loadData(inputPhrase); }, config.get('requestDelay')); } else { loadData(inputPhrase); } } else { hideContainer(); } } break; } function loadData(inputPhrase) { if (inputPhrase.length < config.get('minCharNumber')) { return; } if (config.get('data') !== 'list-required') { var data = config.get('data'); var listBuilders = listBuilderService.init(data); listBuilders = listBuilderService.updateCategories(listBuilders, data); listBuilders = listBuilderService.processData(listBuilders, inputPhrase); loadElements(listBuilders, inputPhrase); if ($field.parent().find('li').length > 0) { showContainer(); } else { hideContainer(); } } var settings = createAjaxSettings(); if (settings.url === undefined || settings.url === '') { settings.url = config.get('url'); } if (settings.dataType === undefined || settings.dataType === '') { settings.dataType = config.get('dataType'); } if (settings.url !== undefined && settings.url !== 'list-required') { settings.url = settings.url(inputPhrase); settings.data = config.get('preparePostData')(settings.data, inputPhrase); $.ajax(settings) .done(function (data) { var listBuilders = listBuilderService.init(data); listBuilders = listBuilderService.updateCategories(listBuilders, data); listBuilders = listBuilderService.convertXml(listBuilders); if (checkInputPhraseMatchResponse(inputPhrase, data)) { listBuilders = listBuilderService.processData(listBuilders, inputPhrase); loadElements(listBuilders, inputPhrase); } if (listBuilderService.checkIfDataExists(listBuilders) && $field.parent().find('li').length > 0) { showContainer(); } else { hideContainer(); } config.get('ajaxCallback')(); }) .fail(function () { logger.warning('Fail to load response data'); }) .always(function () { }); } function createAjaxSettings() { var settings = {}, ajaxSettings = config.get('ajaxSettings') || {}; for (var set in ajaxSettings) { settings[set] = ajaxSettings[set]; } return settings; } function checkInputPhraseMatchResponse(inputPhrase, data) { if (config.get('matchResponseProperty') !== false) { if (typeof config.get('matchResponseProperty') === 'string') { return (data[config.get('matchResponseProperty')] === inputPhrase); } if (typeof config.get('matchResponseProperty') === 'function') { return (config.get('matchResponseProperty')(data) === inputPhrase); } return true; } else { return true; } } } }); } function bindKeydown() { $field .on('keydown', function (evt) { evt = evt || window.event; var keyCode = evt.keyCode; if (keyCode === 38) { suppressKeypress = true; return false; } }) .keydown(function (event) { if (event.keyCode === 13 && selectedElement > -1) { $field.val(config.get('getValue')(elementsList[selectedElement])); config.get('list').onKeyEnterEvent(); config.get('list').onChooseEvent(); selectedElement = -1; hideContainer(); event.preventDefault(); } }); } function bindKeypress() { $field .off('keypress'); } function bindFocus() { $field.focus(function () { if ($field.val() !== '' && elementsList.length > 0) { selectedElement = -1; showContainer(); } }); } function bindBlur() { $field.blur(function () { setTimeout(function () { selectedElement = -1; hideContainer(); }, 250); }); } function removeAutocomplete() { $field.attr('autocomplete', 'off'); } } function showContainer() { $container.trigger('show.eac'); } function hideContainer() { $container.trigger('hide.eac'); } function selectElement(index) { $container.trigger('selectElement.eac', index); } function loadElements(list, phrase) { $container.trigger('loadElements.eac', [list, phrase]); } function loseFieldFocus() { $field.trigger('blur'); } }; scope.eacHandles = []; scope.getHandle = function (id) { return scope.eacHandles[id]; }; scope.inputHasId = function (input) { if ($(input).attr('id') !== undefined && $(input).attr('id').length > 0) { return true; } else { return false; } }; scope.assignRandomId = function (input) { var fieldId = ''; do { fieldId = 'eac-' + Math.floor(Math.random() * 10000); } while ($('#' + fieldId).length !== 0); elementId = scope.consts.getValue('CONTAINER_ID') + fieldId; $(input).attr('id', fieldId); }; scope.setHandle = function (handle, id) { scope.eacHandles[id] = handle; }; return scope; })(EasyAutocomplete || {}); $.fn.easyAutocomplete = function (options) { return this.each(function () { var $this = $(this), eacHandle = new EasyAutocomplete.main($this, options); if (!EasyAutocomplete.inputHasId($this)) { EasyAutocomplete.assignRandomId($this); } eacHandle.init(); EasyAutocomplete.setHandle(eacHandle, $this.attr('id')); }); }; $.fn.getSelectedItemIndex = function () { var inputId = $(this).attr('id'); if (inputId !== undefined) { return EasyAutocomplete.getHandle(inputId).getSelectedItemIndex(); } return -1; }; $.fn.getItems = function () { var inputId = $(this).attr('id'); if (inputId !== undefined) { return EasyAutocomplete.getHandle(inputId).getItems(); } return -1; }; $.fn.getItemData = function (index) { var inputId = $(this).attr('id'); if (inputId !== undefined && index > -1) { return EasyAutocomplete.getHandle(inputId).getItemData(index); } return -1; }; $.fn.getSelectedItemData = function () { var inputId = $(this).attr('id'); if (inputId !== undefined) { return EasyAutocomplete.getHandle(inputId).getSelectedItemData(); } return -1; }; })(jQuery);