/* 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(){ // "use strict"; 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 addEvent(el, type, handler){ if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(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); } 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 = { selector: 0, source: 0, minChars: 3, delay: 150, offsetLeft: 0, offsetTop: 1, cache: 1, menuClass: '', 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){} }; for (var k in options) { if (options.hasOwnProperty(k)) o[k] = options[k]; } // 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; else if (selTop < 0) that.sc.scrollTop = selTop + scrTop; } } } addEvent(window, 'resize', that.updateSC); document.body.appendChild(that.sc); 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', 'mouseover', function(e){ var sel = that.sc.querySelector('.autocomplete-suggestion.selected'); if (sel) sel.className = sel.className.replace('selected', ''); this.className += ' selected'; }, that.sc); 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'; } }, that.sc); that.blurHandler = function(){ try { var over_sb = document.querySelector('.autocomplete-suggestions:hover'); } catch(e){ var 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); }; addEvent(that, 'blur', that.blurHandler); var suggest = function(data){ var val = that.value; that.cache[val] = data; if (data.length && val.length >= o.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; } // no requests if previous suggestions were empty for (var i=1; i