diff --git a/auto-complete.js b/auto-complete.js
index 2f5a88c..0331ba6 100644
--- a/auto-complete.js
+++ b/auto-complete.js
@@ -1,34 +1,38 @@
/*
- JavaScript autoComplete v1.0.4
- Copyright (c) 2014 Simon Steinberger / Pixabay
- GitHub: https://github.com/Pixabay/JavaScript-autoComplete
- License: http://www.opensource.org/licenses/mit-license.php
-*/
+ JavaScript autoComplete v1.0.4
+ Copyright (c) 2014 Simon Steinberger / Pixabay
+ GitHub: https://github.com/Pixabay/JavaScript-autoComplete
+ License: http://www.opensource.org/licenses/mit-license.php
+ */
-var autoComplete = (function(){
+var autoComplete = (function() {
// "use strict";
- function autoComplete(options){
+ function autoComplete(options) {
if (!document.querySelector) return;
// helpers
- function hasClass(el, className){ return el.classList ? el.classList.contains(className) : new RegExp('\\b'+ className+'\\b').test(el.className); }
+ function hasClass(el, className) {
+ return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className);
+ }
- function addEvent(el, type, handler){
- if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
+ function addEvent(el, type, handler) {
+ if (el.attachEvent) el.attachEvent('on' + type, handler); else el.addEventListener(type, handler);
}
- function removeEvent(el, type, handler){
+
+ function removeEvent(el, type, handler) {
// if (el.removeEventListener) not working in IE11
- if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler);
+ if (el.detachEvent) el.detachEvent('on' + type, handler); else el.removeEventListener(type, handler);
}
- function live(elClass, event, cb, context){
- addEvent(context || document, event, function(e){
+
+ function live(elClass, event, cb, context) {
+ addEvent(context || document, event, function(e) {
var found, el = e.target || e.srcElement;
while (el && !(found = hasClass(el, elClass))) el = el.parentElement;
if (found) cb.call(el, e);
});
}
- var o = {
+ var defaultOptions = {
selector: 0,
source: 0,
minChars: 3,
@@ -37,165 +41,205 @@ var autoComplete = (function(){
offsetTop: 1,
cache: 1,
menuClass: '',
- renderItem: function (item, search){
+ renderItem: function(item, search) {
// escape special characters
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
return '
' + item.replace(re, "$1") + '
';
},
- onSelect: function(e, term, item){}
+ onSelect: function(e, term, item) {
+ }
};
- for (var k in options) { if (options.hasOwnProperty(k)) o[k] = options[k]; }
+ for (var option in options) {
+ if (options.hasOwnProperty(option)) defaultOptions[option] = options[option];
+ }
// init
- var elems = typeof o.selector == 'object' ? [o.selector] : document.querySelectorAll(o.selector);
- for (var i=0; i 0)
- that.sc.scrollTop = selTop + that.sc.suggestionHeight + scrTop - that.sc.maxHeight;
+ var scrTop = this.suggestionsContainer.scrollTop, selTop = next.getBoundingClientRect().top - this.suggestionsContainer.getBoundingClientRect().top;
+ if (selTop + this.suggestionsContainer.suggestionHeight - this.suggestionsContainer.maxHeight > 0)
+ this.suggestionsContainer.scrollTop = selTop + this.suggestionsContainer.suggestionHeight + scrTop - this.suggestionsContainer.maxHeight;
else if (selTop < 0)
- that.sc.scrollTop = selTop + scrTop;
+ this.suggestionsContainer.scrollTop = selTop + scrTop;
}
}
- }
- addEvent(window, 'resize', that.updateSC);
- document.body.appendChild(that.sc);
+ };
+ addEvent(window, 'resize', elem.updateSuggestionsContainer);
+ document.body.appendChild(elem.suggestionsContainer);
- live('autocomplete-suggestion', 'mouseleave', function(e){
- var sel = that.sc.querySelector('.autocomplete-suggestion.selected');
- if (sel) setTimeout(function(){ sel.className = sel.className.replace('selected', ''); }, 20);
- }, that.sc);
+ live('autocomplete-suggestion', 'mouseleave', function() {
+ var sel = elem.suggestionsContainer.querySelector('.autocomplete-suggestion.selected');
+ if (sel) setTimeout(function() {
+ sel.className = sel.className.replace('selected', '');
+ }, 20);
+ }, elem.suggestionsContainer);
- live('autocomplete-suggestion', 'mouseover', function(e){
- var sel = that.sc.querySelector('.autocomplete-suggestion.selected');
+ live('autocomplete-suggestion', 'mouseover', function() {
+ var sel = elem.suggestionsContainer.querySelector('.autocomplete-suggestion.selected');
if (sel) sel.className = sel.className.replace('selected', '');
this.className += ' selected';
- }, that.sc);
+ }, elem.suggestionsContainer);
- live('autocomplete-suggestion', 'mousedown', function(e){
+ live('autocomplete-suggestion', 'mousedown', function(e) {
if (hasClass(this, 'autocomplete-suggestion')) { // else outside click
var v = this.getAttribute('data-val');
- that.value = v;
- o.onSelect(e, v, this);
- that.sc.style.display = 'none';
+ elem.value = v;
+ defaultOptions.onSelect(e, v, this);
+ elem.suggestionsContainer.style.display = 'none';
}
- }, that.sc);
+ }, elem.suggestionsContainer);
- that.blurHandler = function(){
- try { var over_sb = document.querySelector('.autocomplete-suggestions:hover'); } catch(e){ var over_sb = 0; }
+ elem.blurHandler = function() {
+ var that = this,
+ over_sb;
+ try {
+ over_sb = document.querySelector('.autocomplete-suggestions:hover');
+ } catch (e) {
+ over_sb = 0;
+ }
if (!over_sb) {
- that.last_val = that.value;
- that.sc.style.display = 'none';
- setTimeout(function(){ that.sc.style.display = 'none'; }, 350); // hide suggestions on fast input
- } else if (that !== document.activeElement) setTimeout(function(){ that.focus(); }, 20);
+ this.last_val = this.value;
+ this.suggestionsContainer.style.display = 'none';
+ setTimeout(function() {
+ that.suggestionsContainer.style.display = 'none';
+ }, 350); // hide suggestions on fast input
+ } else if (this !== document.activeElement) setTimeout(function() {
+ this.focus();
+ }, 20);
};
- addEvent(that, 'blur', that.blurHandler);
+ addEvent(elem, 'blur', elem.blurHandler);
- var suggest = function(data){
- var val = that.value;
- that.cache[val] = data;
- if (data.length && val.length >= o.minChars) {
+ var suggest = function(data) {
+ var val = elem.value;
+ elem.cache[val] = data;
+ if (data.length && val.length >= defaultOptions.minChars) {
var s = '';
- for (var i=0;i 40) && key != 13 && key != 27) {
- var val = that.value;
- if (val.length >= o.minChars) {
- if (val != that.last_val) {
- that.last_val = val;
- clearTimeout(that.timer);
- if (o.cache) {
- if (val in that.cache) { suggest(that.cache[val]); return; }
+ var val = this.value;
+ if (val.length >= defaultOptions.minChars) {
+ if (val != this.last_val) {
+ this.last_val = val;
+ clearTimeout(this.timer);
+ if (defaultOptions.cache) {
+ if (val in this.cache) {
+ suggest(this.cache[val]);
+ return;
+ }
// no requests if previous suggestions were empty
- for (var i=1; iAdvanced suggestions handling and custom layout
minChars: 1,
source: function(term, suggest){
term = term.toLowerCase();
- var choices = ['ActionScript', 'AppleScript', 'Asp', 'Assembly', 'BASIC', 'Batch', 'C', 'C++', 'CSS', 'Clojure', 'COBOL', 'ColdFusion', 'Erlang', 'Fortran', 'Groovy', 'Haskell', 'HTML', 'Java', 'JavaScript', 'Lisp', 'Perl', 'PHP', 'PowerShell', 'Python', 'Ruby', 'Scala', 'Scheme', 'SQL', 'TeX', 'XML'];
+ var choices = ['ActionScript', 'AppleScript', 'Asp', 'Assembly', 'BASIC', 'Batch', 'C', 'C++', 'CSS', 'Clojure', 'COBOL', 'ColdFusion', 'Erlang', 'Fortran', 'Groovy', 'Haskell', 'HTML', 'Java', 'JavaScript', 'Plankalkül', 'Lisp', 'Perl', 'PHP', 'PowerShell', 'Python', 'Ruby', 'Scala', 'Scheme', 'SQL', 'TeX', 'XML'];
var suggestions = [];
for (i=0;i