jquery-autocomplete-js
Version:
The simplest jQuery plugin for creating autocomplete boxes with dynamically generated suggestions.
939 lines (855 loc) • 29.5 kB
JavaScript
/**
* autocomplete.js 1.1.0
* jQuery plugin
* Remake of the complete-ly.js (c) by Lorenzo Puccetti - 2013
* isis97 - Styczynsky Digital Systems
*
* See the live examples at:
* http://isis97.github.io/autocomplete-js/
*
* And view the Github project:
* https://github.com/isis97/autocomplete-js
*
*
* MIT Licensing
* Copyright (c) 2015 Piotr Aleksander Styczynski
*
* This Software shall be used for doing good things, not bad things.
* - Lorenzo Puccetti
*
* This is a simple autocomple library.
* The autocomple.js supports dynamic suggestions and history browsing.
* To set up autocomplete just use jQuery $('#div').autocomplete({ options: ["apple", "bannana", "strawberry", "pineapple"] })
*
* You can easily manipulate the suggestions list and history directly:
*
* var ac = $('#div').autocomplete({ options: ["apple", "bannana", "strawberry", "pineapple"] });
* ac.options = ["nope"]; //override suggestions list
* ac.historyInput = []; //clear history
* ac.options = [ {name:"option", "description":"description of the option", html: true} ] //Advanced suggestions (with descriptions)
*
**/
(function($){
$.fn.extend({
autocomplete: function(settings) {
var container = $(this);
var rs = {};
var createEventHandler = function(backHandlerCallback) {
backHandlerCallback = backHandlerCallback || function(){};
return {
handlers: [],
__back_handler: backHandlerCallback,
push: function(handler) {
this.handlers.push(handler);
},
call: function(args) {
t = rs;
args = args || [t];
this.__back_handler.apply(t, args);
for(var i=0;i<this.handlers.length;++i) {
this.handlers[i].apply(t, args);
}
}
};
};
if(settings == null || settings == {} || settings == undefined) {
return null;
}
if(container.length > 1) {
var ret = [];
for(var i=0;i>container.length;++i) {
ret.push($(container[i]).autocomplete(settings));
}
return ret;
}
settings = settings || {};
if(settings.scrollController === 'nanoscroller') {
var c = {
scroller: null,
scrollerPos: 0,
init: function(e) {
e.css('overflow', 'hidden');
var contentWrapper = $( '<div class="nano-content"></div>' );
e.wrapInner(contentWrapper);
var nanoWrapper = $('<div class="nano"></div>');
e.wrapInner(nanoWrapper);
return contentWrapper;
},
repaint: function(e) {
if(!this.scroller) {
this.scroller = e.parent();
this.scroller.nanoScroller({ alwaysVisible: true });
this.scroller.on("update", function(event, vals){
c.scrollerPos = vals.position;
});
}
this.scroller.nanoScroller({ scrollTop: 0 });
this.scroller.nanoScroller();
},
scroll: function(value) {
if(!this.scroller) return 0;
if(value) {
this.scroller.nanoScroller({ scrollTop: value });
}
return this.scrollerPos;
}
};
settings.scrollController = c;
}
settings.scrollController = settings.scrollController || {
init: function(e) {
return e;
},
repaint: function(e) {
},
scroll: function(value) {
if(value) dropDown.scrollTop(value);
return dropDown.scrollTop();
}
};
settings.scrollController.init = settings.scrollController.init || function(e){return e};
settings.scrollController.repaint = settings.scrollController.repaint || function(){};
settings.scrollController.scroll = settings.scrollController.scroll || function(value){if(value) dropDown.scrollTop(value);return dropDown.scrollTop();};
settings.__event_hintChanged = createEventHandler();
settings.__event_dropdownShown = createEventHandler(function(e) {e.show();});
settings.__event_dropdownHidden = createEventHandler(function(e) {e.hide();});
settings.__event_confirmed = createEventHandler();
settings.__event_changed = createEventHandler();
settings.__event_history_browsed = createEventHandler();
settings.__event_key = createEventHandler();
if(settings.animation) {
var perfOP = function(e, dir) {
for(var i=0;i<settings.animation.length;++i) {
var key = settings.animation[i][0];
var value = null;
if(dir) {
value = settings.animation[i][1];
} else {
value = settings.animation[i][2];
}
if(key=='height') {
e.height(value);
} else if(key=='width') {
e.width(value);
} else {
e.css(key, value);
}
}
};
var generateOP = function(dir) {
var o = {};
for(var i=0;i<settings.animation.length;++i) {
var key = settings.animation[i][0];
var value = null;
if(dir) {
value = settings.animation[i][1];
} else {
value = settings.animation[i][2];
}
o[key] = value;
}
return o;
};
settings.__event_dropdownShown.push(function(e) {
var thiz = this;
e.stop().show();
perfOP(e, true);
e.animate(
generateOP(false),
500,
function(){
thiz.repaint();
}
);
});
settings.__event_dropdownHidden.push(function(e) {
var thiz = this;
e.stop().show();
perfOP(e, false);
e.animate(
generateOP(true),
500,
function(){
e.hide();
}
);
});
}
settings.showWhenEmpty = settings.showWhenEmpty || false;
settings.isDisabled = settings.isDisabled || false;
settings.inputWidth = settings.inputWidth || '100%';
settings.inputHeight = settings.inputHeight || '25px';
settings.dropDownWidth = settings.dropDownWidth || '50%';
settings.dropDownDescriptionBoxWidth = settings.dropDownDescriptionBoxWidth || '50%';
settings.fontSize = settings.fontSize || null;
settings.fontFamily = settings.fontFamily || null;
settings.formPromptHTML = settings.formPromptHTML || '';
settings.color = settings.color || null;
settings.hintColor = settings.hintColor || null;
settings.backgroundColor = settings.backgroundColor || null;
settings.dropDownBorderColor = settings.dropDownBorderColor || null;
settings.dropDownZIndex = settings.dropDownZIndex || '100';
settings.dropDownOnHoverBackgroundColor = settings.dropDownOnHoverBackgroundColor || null;
settings.enableHistory = settings.enableHistory || true;
settings.inputHistory = settings.inputHistory || [];
settings.classes = settings.classes || {};
settings.classes.input = settings.classes.input || null;
settings.classes.dropdown = settings.classes.dropdown || null;
settings.classes.hint = settings.classes.hint || null;
settings.classes.wrapper = settings.classes.wrapper || null;
settings.classes.prompt = settings.classes.prompt || null;
settings.classes.hoverItem = settings.classes.hoverItem || null;
settings.classes.row = settings.classes.row || null;
settings.classes.descriptionBox = settings.classes.descriptionBox || null;
settings.maxSuggestionsCount = settings.maxSuggestionsCount || 100;
settings.suggestionBoxHeight = settings.suggestionBoxHeight || '75px';
settings.showDropDown = settings.showDropDown || false;
settings.dropDownPosition = settings.dropDownPosition || 'bottom';
settings.blockEvents = settings.blockEvents || true;
settings.options = settings.options || {};
var formInput = $('<input class="autocomplete autocomplete-input autocomplete-text" type="text" spellcheck="false"></input>')
.css('width', settings.inputWidth)
.css('height', settings.inputHeight)
.css('outline', '0')
.css('border', '0')
.css('margin', '0')
.css('padding', '0')
.css('verticalAlign', 'top')
.css('position', 'absolute')
//.css('background-color', 'transparent')
.addClass(settings.classes.input);
var formHint = formInput.clone()
.removeClass('autocomplete-input')
.css('background-color', '')
.css('width', settings.inputWidth)
.css('height', settings.inputHeight)
.attr('disabled', '')
.css('position', 'absolute')
.css('top', 'inherit')
.css('left', 'inherit')
.css('borderColor', 'transparent')
.css('boxShadow', 'none')
.css('color', settings.hintColor)
.addClass('autocomplete-hint')
.addClass(settings.classes.hint);
formInput.css('background', 'none');
formHint.__val = formHint.val;
formHint.val = function(text) {
if((text == undefined) || (text == null)) {
return formHint.__val();
}
formHint.__val(text);
settings.__event_hintChanged.call([rs, text]);
};
var formWrapper = $('<div class="autocomplete autocomplete-wrapper"></div>')
.css('display', 'inline')
.css('width', settings.inputWidth)
.css('height', settings.inputHeight)
.css('position', 'absolute')
.css('bottom', '0px')
.css('outline', '0')
.css('border', '0')
.css('margin', '0')
.css('padding', '0')
.css('paddingTop', '10px')
.addClass(settings.classes.wrapper);
var formPrompt = $('<div class="autocomplete autocomplete-prompt"></div>')
.css('position', 'absolute')
.css('outline', '0')
.css('margin', '0')
.css('padding', '0')
.css('border', '0')
.css('top', '0')
.css('left', '0')
.css('overflow', 'hidden')
.html(settings.formPromptHTML)
.addClass(settings.classes.prompt);
if ($('body') === undefined) {
throw 'document.body is undefined. The library was wired up incorrectly.';
}
$('body').append(formPrompt);
var w = formPrompt.width();
formWrapper.append(formPrompt);
formPrompt
.show()
.css('left', '-' + w + 'px')
.css('marginLeft', w + 'px');
var dropDown = $('<div class="autocomplete autocomplete-dropdown"></div>')
/*.css('position', 'absolute')
.css('top', settings.suggestionBoxHeight)*/
.css('height', settings.suggestionBoxHeight)
.css('width', settings.dropDownWidth)
.hide();
var dropDownTopOffset = dropDown.height()/2;
if(settings.dropDownPosition == 'top') {
dropDownTopOffset = -(dropDown.height()/2)-formInput.height();
}
dropDown
.css('float', 'bottom')
.css('position', 'absolute')
.css('z-index', '9999')
.css('left', '0px')
.css('top', dropDownTopOffset+'px')
.css('outline', '0')
.css('margin', '0')
.css('padding', '0')
.css('text-align', 'left')
.css('font-size', settings.fontSize)
.css('font-family', settings.fontFamily)
.css('max-height', settings.suggestionBoxHeight)
.css('background-color', settings.backgroundColor)
.css('z-index', settings.dropDownZIndex)
.css('cursor', 'default')
.css('border-style', 'solid')
.css('border-width', '1px')
.css('border-color', settings.dropDownBorderColor)
.css('overflow-x', 'hidden')
.css('white-space', 'pre')
.css('overflow-y', 'scroll')
.addClass(settings.classes.dropdown);
var dropDownDescriptionBox = $('<div class="autocomplete autocomplete-dropdown-description-box"></div>')
.css('position', 'absolute')
.css('left', settings.dropDownWidth)
.css('top', dropDownTopOffset+'px')
/*.css('top', '-'+settings.suggestionBoxHeight)*/
.hide()
.css('word-break', 'keep-all')
.css('white-space', 'normal')
.css('outline', '0')
.css('margin', '0')
.css('padding', '0')
.css('text-align', 'left')
.css('font-size', settings.fontSize)
.css('font-family', settings.fontFamily)
.css('max-height', settings.suggestionBoxHeight)
.css('background-color', settings.backgroundColor)
.css('z-index', settings.dropDownZIndex)
.css('cursor', 'default')
.css('border-style', 'solid')
.css('border-width', '1px')
.css('border-color', settings.dropDownBorderColor)
.css('overflow-x', 'hidden')
.css('color', settings.color)
//.css('overflow-y', 'scroll')
.css('height', settings.suggestionBoxHeight)
.css('width', settings.dropDownDescriptionBoxWidth)
.addClass(settings.classes.descriptionBox);
dropDownDescriptionBox.hideBlock = function () {
dropDownDescriptionBox.attr('display', 'none');
};
dropDownDescriptionBox.showBlock = function () {
dropDownDescriptionBox.attr('display', 'block');
};
var escapeHtml = function(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
var extractOption = function(elem) {
var opt_name = "";
var opt_description = null;
elem = elem || {};
if(elem.html == undefined || elem.html == null) {
elem.html = false;
}
if(elem.name != undefined && elem.name != null) {
opt_name = elem.name;
if(elem.description) {
opt_description = elem.description;
if(!elem.html) {
if(opt_description) {
opt_description = escapeHtml(opt_description);
}
}
}
} else {
opt_name = elem;
}
opt_name = opt_name || '';
opt_description = opt_description || null;
elem.html = elem.html || false;
return {name:opt_name, description:opt_description, html:elem.html};
};
var createDropDownController = function(elem) {
var rows = [];
var ix = 0;
var oldIndex = -1;
var onMouseOver = function() {
$(this).css('outline', '1px solid #ddd');
}
var onMouseOut = function() {
$(this).css('outline', '0');
}
var onMouseDown = function() {
p.hideBlock();
p.onMouseSelected(this.__hint);
}
var p = {
contentElem: elem,
hideBlock: function () {
elem.attr('display', 'none');
},
showBlock: function (optsPrev) {
var opts = this.contentElem.children().length;
var doCall = false;
var doCallHidden = false;
if(optsPrev<=1 && opts>1) {
doCall = true;
} else if(optsPrev>1 && opts<=1) {
doCallHidden = true;
}
elem.attr('display', 'block');
if(doCall) {
settings.__event_dropdownShown.call([dropDown]);
}
if(doCallHidden) {
this.hideBlock();
settings.__event_dropdownHidden.call([dropDown]);
}
},
hide: function() {
this.hideBlock();
},
refresh: function(token, array) {
//this.hide();
ix = 0;
this.contentElem.html("");
var vph = (window.innerHeight || document.documentElement.clientHeight);
var distanceToTop = elem.offset().top - 6;
var distanceToBottom = vph - (elem.parent().height() - elem.height() - elem.offset().top) - 6;
rows = [];
var maxOptionsCount = 100;
var curOptionsCount = 0;
for (var i = 0; i < array.length; i++) {
var opt = extractOption(array[i]);
var opt_name = opt.name;
var opt_description = opt.description;
if (opt_name.toLowerCase().indexOf(token.toLowerCase()) === 0) {
++curOptionsCount;
if (curOptionsCount > settings.maxSuggestionsCount) {
break;
}
var divRow = $('<div></div>')
.css('color', settings.color)
.mouseover(onMouseOver)
.mouseout(onMouseOut)
.mousedown(onMouseDown)
.addClass(settings.classes.row);
divRow[0].__hint = divRow.__hint = opt_name;
divRow.html(token + '<b>' + opt_name.substring(token.length) + '</b>');
divRow.description = opt_description;
rows.push(divRow);
this.contentElem.append(divRow);
}
}
if(rows.length>1) {
if(rows[0].description) {
dropDownDescriptionBox.show();
if(rows[0].html) {
dropDownDescriptionBox.html(rows[0].description);
} else {
dropDownDescriptionBox.text(rows[0].description);
}
} else {
dropDownDescriptionBox.hide();
}
} else {
dropDownDescriptionBox.hide();
return;
}
if (rows.length === 0) {
return;
}
if (rows.length === 1 && token === rows[0].__hint) {
return;
}
if (rows.length < 2) return;
p.highlight(0);
if (distanceToTop > distanceToBottom * 3) {
elem
.css('maxHeight', distanceToTop + 'px')
/*.css('top', '')*/
.css('bottom', '100%');
} else {
elem
/*.css('top', '100%')*/
.css('bottom', '')
.css('maxHeight', distanceToBottom + 'px');
}
elem.show();
},
highlight: function(index) {
if (oldIndex != -1 && rows[oldIndex]) {
rows[oldIndex].css('backgroundColor', settings.backgroundColor);
}
dropDown.find(settings.classes.hoverItem).removeClass(settings.classes.hoverItem);
var oldFocusedItem = dropDown.find('.autocomplete-hover-item');
oldFocusedItem.removeClass(settings.classes.hoverItem);
oldFocusedItem.removeClass('autocomplete-hover-item');
if(rows[index].description) {
dropDownDescriptionBox.show();
if(rows[index].html) {
dropDownDescriptionBox.html(rows[index].description);
} else {
dropDownDescriptionBox.text(rows[index].description);
}
} else {
dropDownDescriptionBox.hide();
}
rows[index].css('backgroundColor', settings.dropDownOnHoverBackgroundColor);
rows[index].addClass(settings.classes.hoverItem);
rows[index].addClass('autocomplete-hover-item');
oldIndex = index;
},
scrollController: settings.scrollController,
move: function(step) {
if (!elem.is(':visible')) return '';
if (ix + step === -1 || ix + step === rows.length) return rows[ix].__hint;
ix += step;
p.highlight(ix);
this.scrollController.scroll(this.scrollController.scroll() + step * this.contentElem.children().height());
return rows[ix].__hint;
},
onMouseSelected: function() {}
};
return p;
}
var dropDownController = createDropDownController(dropDown);
dropDownController.onMouseSelected = function(text) {
formInput.val(leftSide + text);
formHint.val(leftSide + text);
rs.onChange(formInput.val());
registerOnTextChangeOldValue = formInput.val();
setTimeout(function() {
formInput.focus();
}, 0);
}
if(!settings.showDropDown) {
dropDown.css('visibility', 'hidden');
dropDown.css('display', 'none');
dropDownDescriptionBox.css('visibility', 'hidden');
dropDownDescriptionBox.css('display', 'none');
} else {
formWrapper.append(dropDown);
formWrapper.append(dropDownDescriptionBox);
}
formWrapper.append(formHint);
formWrapper.append(formInput);
container.append(formWrapper);
var spacer;
var leftSide;
function calculateWidthForText(text) {
if (spacer === undefined) {
spacer = $('<span></span>')
.hide()
.css('position', 'fixed')
.css('outline', '0')
.css('margin', '0')
.css('padding', '0')
.css('border', '0')
.css('left', '0')
.css('white-space', 'pre')
.css('font-size', settings.fontSize)
.css('font-family', settings.fontFamily)
.css('font-weight', 'normal');
$("body").append(spacer);
}
spacer.text(text);
var t = spacer.width();
spacer.remove();
return t;
}
rs = {
status: !settings.isDisabled,
/*settings.__event_dropdownShown = createEventHandler();
settings.__event_dropdownHidden = createEventHandler();
settings.__event_confirmed = createEventHandler();
settings.__event_changed = createEventHandler();
settings.__event_history_browsed = createEventHandler();
settings.__event_key = createEventHandler();*/
hintChanged: function(callback) { settings.__event_hintChanged.push(callback); return this; },
dropdownShown: function(callback) { settings.__event_dropdownShown.push(callback); return this; },
dropdownHidden: function(callback) { settings.__event_dropdownHidden.push(callback); return this; },
confirmed: function(callback) { settings.__event_confirmed.push(callback); return this; },
changed: function(callback) { settings.__event_changed.push(callback); return this; },
historyBrowsed: function(callback) { settings.__event_history_browsed.push(callback); return this; },
key: function(callback) { settings.__event_key.push(callback); return this; },
onKey: function(e) {
settings.__event_key.call([e, e.which]);
return this;
},
disable: function() {
this.status = false;
return this;
},
enable: function() {
this.status = true;
return this;
},
showDropDown: function() {
dropDown.show();
settings.__event_dropdownShown.call([dropDown]);
this.repaint();
},
isEnabled: function() {
return this.status;
},
onArrowDown: function() {return this;},
onArrowUp: function() {return this;},
onEnter: function() {
this.inputHistory.push(formInput.val());
settings.__event_confirmed.call([this, this.getText()]);
return this;
},
onTab: function() {return this;},
onChange: function() {
settings.__event_changed.call([this, this.getText()]);
rs.repaint();
return this;
},
onHistoryPrev: function() {
settings.__event_history_browsed.call([this, this.getInputHistory()]);
formInput.val(this.historyNavigatePrev());
return this;
},
onHistoryNext: function() {
settings.__event_history_browsed.call([this, this.getInputHistory()]);
formInput.val(this.historyNavigateNext());
return this;
},
getInputHistory: function() {
return this.inputHistory;
},
getOptions: function() {
if(this.options instanceof Function) {
var text = formInput.val();
var startFrom = rs.startFrom;
var tokens = text.substring(startFrom).split(" ");
var token = tokens[tokens.length - 1];
return this.options(this, text, token);
}
return this.options;
},
startFrom: 0,
options: settings.options,
inputHistory: settings.inputHistory,
historyIndex: 0,
historyBrowsingActive: false,
formWrapper: formWrapper,
input: formInput,
hint: formHint,
dropDown: dropDown,
formPrompt: formPrompt,
historyNavigateNext: function() {
this.historyIndex++;
if(this.historyIndex >= this.inputHistory.length) {
this.historyIndex = this.inputHistory.length - 1;
}
return this.inputHistory[this.historyIndex];
},
historyNavigatePrev: function() {
this.historyIndex--;
if(this.historyIndex < 0) {
this.historyIndex = 0;
}
return this.inputHistory[this.historyIndex];
},
historyNavigateClear: function() {
this.historyIndex = this.inputHistory.length - 1;
},
setText: function(text) {
formHint.val(text);
formInput.val(text);
return this;
},
getText: function() {
return formInput.val();
},
pullText: function() {
var t = this.getText();
this.setText('');
return t;
},
hideDropDown: function() {
dropDownController.hide();
return this;
},
repaint: function() {
var finish = (function(){
dropDownController.scrollController.repaint(dropDownController.contentElem);
});
var text = formInput.val();
var startFrom = rs.startFrom;
var options = rs.getOptions();
var optionsLength = options.length;
var tokens = text.substring(startFrom).split(" ");
var token = tokens[tokens.length - 1];
leftSide = "";
for (var i = 0; i < tokens.length - 1; ++i) {
leftSide += tokens[i] + " ";
}
formHint.val('');
for (var i = 0; i < optionsLength; i++) {
var opt = extractOption(options[i]);
var opt_name = opt.name;
if(opt_name.indexOf == undefined) {
console.log(opt_name);
throw "NOPE!";
}
if (opt_name.indexOf(token) === 0) {
formHint.val(leftSide + opt_name);
break;
}
}
var doShowBlock = false;
var showBlockOptionsOldNumber = dropDownController.contentElem.children().length;
if(!this.status) {
dropDownController.hideBlock();
dropDownDescriptionBox.hideBlock();
finish();
return this;
} else {
doShowBlock = true;
}
dropDown.css('left', calculateWidthForText(leftSide) + 'px');
if (token == '') {
if(settings.showWhenEmpty) {
dropDownController.refresh(token, rs.getOptions());
} else {
dropDownController.refresh(token, []);
}
} else {
dropDownController.refresh(token, rs.getOptions());
}
if(doShowBlock) {
dropDownController.showBlock(showBlockOptionsOldNumber);
dropDownDescriptionBox.showBlock();
}
finish();
}
};
var registerOnTextChangeOldValue;
var registerOnTextChange = function(txt, callback) {
registerOnTextChangeOldValue = txt.val();
var handler = function() {
var value = txt.val();
if (registerOnTextChangeOldValue !== value) {
registerOnTextChangeOldValue = value;
callback(value);
}
};
txt.change(handler);
txt.keyup(handler);
};
registerOnTextChange(formInput, function(text) {
rs.onChange(text);
});
var keyDownHandler = function(e) {
e = e || window.event;
var keyCode = e.keyCode;
var prevent = function(event) {
if(settings.blockEvents) {
event.preventDefault();
}
}
if(formInput.val() == "") {
rs.historyBrowsingActive = true;
}
/*
if (keyCode == 33) {
return;
} // page up
else if (keyCode == 34) {
return;
} // page down
*/
if (keyCode == 27) { //escape
prevent(e);
dropDownController.hide();
dropDownDescriptionBox.hide();
formHint.val(formInput.val());
formInput.focus();
return this;
} else if (keyCode == 39 || keyCode == 35 || keyCode == 9) {
prevent(e);
if (keyCode == 9) {
e.preventDefault();
e.stopPropagation();
if (formHint.val().length == 0) {
rs.onTab();
rs.onKey(e);
}
}
if (formHint.val().length > 0) {
dropDownController.hide();
dropDownDescriptionBox.hide();
formInput.val(formHint.val());
var hasTextChanged = registerOnTextChangeOldValue != formInput.val()
registerOnTextChangeOldValue = formInput.val();
if (hasTextChanged) {
rs.onChange(formInput.val());
}
}
return this;
} else if (keyCode == 13) { //enter
prevent(e);
if (formHint.val().length == 0) {
rs.onEnter();
} else {
var wasDropDownHidden = (!dropDown.is(':visible'));
dropDownController.hide();
if (wasDropDownHidden) {
formHint.val(formInput.val());
formInput.focus();
rs.onEnter();
return this;
}
formInput.val(formHint.val());
var hasTextChanged = registerOnTextChangeOldValue != formInput.val()
registerOnTextChangeOldValue = formInput.val();
if (hasTextChanged) {
rs.onChange(formInput.val());
}
}
return this;
} else if (keyCode == 40) { // down
prevent(e);
if(settings.enableHistory && rs.historyBrowsingActive) {
rs.onHistoryPrev();
} else {
var m = dropDownController.move(+1);
if (m == '') {
rs.onArrowDown();
}
formHint.val(leftSide + m);
return this;
}
} else if (keyCode == 38) { // up
prevent(e);
if(settings.enableHistory && rs.historyBrowsingActive) {
rs.onHistoryNext();
} else {
var m = dropDownController.move(-1);
if (m == '') {
rs.onArrowUp();
}
formHint.val(leftSide + m);
}
return this;
} else {
rs.historyBrowsingActive = false;
rs.historyNavigateClear();
rs.onKey(e);
}
formHint.val('');
return this;
};
formInput.keydown(keyDownHandler);
dropDownController.contentElem = dropDownController.scrollController.init(dropDown);
return rs;
}
});
})($);