Created
January 30, 2018 16:59
-
-
Save alimoshen/b94cea3a6ad8360752fd1fd01374adce to your computer and use it in GitHub Desktop.
easyAutocomplete
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* easy-autocomplete | |
* jQuery plugin for autocompletion | |
* | |
* @author Łukasz Pawełczak (http://github.com/pawelczak) | |
* @version 1.3.5 | |
* Copyright License: | |
*/ | |
/* | |
* EasyAutocomplete - Configuration | |
*/ | |
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) { | |
if (element.search(phrase) > -1) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
}, | |
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() { | |
if (defaults.url === "list-required" && defaults.data === "list-required") { | |
return false; | |
} | |
return true; | |
}; | |
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) { | |
if (element.search(phrase) > -1) { | |
return true; | |
} else { | |
return false; | |
} | |
}; | |
} | |
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) { | |
if (defaults[name] !== undefined && defaults[name] !== null) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
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" && $.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 - Constans | |
*/ | |
var EasyAutocomplete = (function(scope){ | |
scope.Constans = function Constans() { | |
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 proccessData(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(); | |
} | |
if (config.get("list").match.method(value, phrase)) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
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" | |
}, | |
lawyer: { | |
type: "lawyer", | |
fields: { | |
lawyerimage: "lawyerimage", | |
lawyerrole: "laywerrole", | |
lawyername: "lawyername", | |
lawyerexpertise: "lawyerexpertise" | |
}, | |
method: function(element) { | |
return element | |
}, | |
cssClass: "lawyerListing" | |
}, | |
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; | |
} | |
lawyerimage: "lawyerimage", | |
lawyerrole: "laywerrole", | |
lawyername: "lawyername", | |
lawyerexpertise: "lawyerexpertise" | |
if (template.type === "lawyer") { | |
if (typeof _fields.lawyerimage === "string") { | |
buildMethod = function(elementValue, element) { | |
return elementValue + "<div class='laywerResult'><div class='profileImage'><img src='" + element[_fields.lawyerimage] + "' /></div><div class='profileText'><h3>"+ element[_fields.lawyername] +"</h3><h4> "+ element[_fields.lawyerrole] +" </h4><p>"+ element[_fields.lawyerexpertise] +"</p></div>"; | |
}; | |
} else if (typeof _fields.lawyerimage === "function") { | |
buildMethod = function(elementValue, element) { | |
return elementValue + "<div class='laywerResult'><div class='profileImage'><img src='" + _fields.lawyerimage(element) + "' /></div><div class='profileText'><h3>"+ _fields.lawyername(element) +"</h3><h4> "+ _fields.lawyerrole(element) +" </h4><p>"+ _fields.lawyerexpertise(element) +"</p></div>"; | |
}; | |
} | |
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.Constans(), | |
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() { | |
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) { | |
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 || {}); | |
(function($) { | |
$.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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment