forked from matcornic/hugo-theme-learn
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace horsey with Pixabay's autocomplete (matcornic#75)
- Loading branch information
1 parent
38b9c0b
commit de79b13
Showing
7 changed files
with
299 additions
and
1,633 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
.autocomplete-suggestions { | ||
text-align: left; | ||
cursor: default; | ||
border: 1px solid #ccc; | ||
border-top: 0; | ||
background: #fff; | ||
box-shadow: -1px 1px 3px rgba(0,0,0,.1); | ||
|
||
/* core styles should not be changed */ | ||
position: absolute; | ||
display: none; | ||
z-index: 9999; | ||
max-height: 254px; | ||
overflow: hidden; | ||
overflow-y: auto; | ||
box-sizing: border-box; | ||
|
||
} | ||
.autocomplete-suggestion { | ||
position: relative; | ||
cursor: pointer; | ||
padding: 7px; | ||
line-height: 23px; | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
color: #333; | ||
} | ||
|
||
.autocomplete-suggestion b { | ||
font-weight: normal; | ||
color: #1f8dd6; | ||
} | ||
|
||
.autocomplete-suggestion.selected { | ||
background: #333; | ||
color: #fff; | ||
} | ||
|
||
.autocomplete-suggestion:hover { | ||
background: #444; | ||
color: #fff; | ||
} | ||
|
||
.autocomplete-suggestion > .context { | ||
font-size: 12px; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
/* | ||
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 '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>'; | ||
}, | ||
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<elems.length; i++) { | ||
var that = elems[i]; | ||
|
||
// create suggestions container "sc" | ||
that.sc = document.createElement('div'); | ||
that.sc.className = 'autocomplete-suggestions '+o.menuClass; | ||
|
||
that.autocompleteAttr = that.getAttribute('autocomplete'); | ||
that.setAttribute('autocomplete', 'off'); | ||
that.cache = {}; | ||
that.last_val = ''; | ||
|
||
that.updateSC = function(resize, next){ | ||
var rect = that.getBoundingClientRect(); | ||
that.sc.style.left = Math.round(rect.left + (window.pageXOffset || document.documentElement.scrollLeft) + o.offsetLeft) + 'px'; | ||
that.sc.style.top = Math.round(rect.bottom + (window.pageYOffset || document.documentElement.scrollTop) + o.offsetTop) + 'px'; | ||
that.sc.style.width = Math.round(rect.right - rect.left) + 'px'; // outerWidth | ||
if (!resize) { | ||
that.sc.style.display = 'block'; | ||
if (!that.sc.maxHeight) { that.sc.maxHeight = parseInt((window.getComputedStyle ? getComputedStyle(that.sc, null) : that.sc.currentStyle).maxHeight); } | ||
if (!that.sc.suggestionHeight) that.sc.suggestionHeight = that.sc.querySelector('.autocomplete-suggestion').offsetHeight; | ||
if (that.sc.suggestionHeight) | ||
if (!next) that.sc.scrollTop = 0; | ||
else { | ||
var scrTop = that.sc.scrollTop, selTop = next.getBoundingClientRect().top - that.sc.getBoundingClientRect().top; | ||
if (selTop + that.sc.suggestionHeight - that.sc.maxHeight > 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<data.length;i++) s += o.renderItem(data[i], val); | ||
that.sc.innerHTML = s; | ||
that.updateSC(0); | ||
} | ||
else | ||
that.sc.style.display = 'none'; | ||
} | ||
|
||
that.keydownHandler = function(e){ | ||
var key = window.event ? e.keyCode : e.which; | ||
// down (40), up (38) | ||
if ((key == 40 || key == 38) && that.sc.innerHTML) { | ||
var next, sel = that.sc.querySelector('.autocomplete-suggestion.selected'); | ||
if (!sel) { | ||
next = (key == 40) ? that.sc.querySelector('.autocomplete-suggestion') : that.sc.childNodes[that.sc.childNodes.length - 1]; // first : last | ||
next.className += ' selected'; | ||
console.log(next); | ||
that.value = next.getAttribute('data-val'); | ||
} else { | ||
next = (key == 40) ? sel.nextSibling : sel.previousSibling; | ||
if (next) { | ||
sel.className = sel.className.replace('selected', ''); | ||
next.className += ' selected'; | ||
that.value = next.getAttribute('data-val'); | ||
} | ||
else { sel.className = sel.className.replace('selected', ''); that.value = that.last_val; next = 0; } | ||
} | ||
that.updateSC(0, next); | ||
return false; | ||
} | ||
// esc | ||
else if (key == 27) { that.value = that.last_val; that.sc.style.display = 'none'; } | ||
// enter | ||
else if (key == 13 || key == 9) { | ||
var sel = that.sc.querySelector('.autocomplete-suggestion.selected'); | ||
if (sel && that.sc.style.display != 'none') { o.onSelect(e, sel.getAttribute('data-val'), sel); setTimeout(function(){ that.sc.style.display = 'none'; }, 20); } | ||
} | ||
}; | ||
addEvent(that, 'keydown', that.keydownHandler); | ||
|
||
that.keyupHandler = function(e){ | ||
var key = window.event ? e.keyCode : e.which; | ||
if (!key || (key < 35 || key > 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<val.length-o.minChars; i++) { | ||
var part = val.slice(0, val.length-i); | ||
if (part in that.cache && !that.cache[part].length) { suggest([]); return; } | ||
} | ||
} | ||
that.timer = setTimeout(function(){ o.source(val, suggest) }, o.delay); | ||
} | ||
} else { | ||
that.last_val = val; | ||
that.sc.style.display = 'none'; | ||
} | ||
} | ||
}; | ||
addEvent(that, 'keyup', that.keyupHandler); | ||
|
||
that.focusHandler = function(e){ | ||
that.last_val = '\n'; | ||
that.keyupHandler(e) | ||
}; | ||
if (!o.minChars) addEvent(that, 'focus', that.focusHandler); | ||
} | ||
|
||
// public destroy method | ||
this.destroy = function(){ | ||
for (var i=0; i<elems.length; i++) { | ||
var that = elems[i]; | ||
removeEvent(window, 'resize', that.updateSC); | ||
removeEvent(that, 'blur', that.blurHandler); | ||
removeEvent(that, 'focus', that.focusHandler); | ||
removeEvent(that, 'keydown', that.keydownHandler); | ||
removeEvent(that, 'keyup', that.keyupHandler); | ||
if (that.autocompleteAttr) | ||
that.setAttribute('autocomplete', that.autocompleteAttr); | ||
else | ||
that.removeAttribute('autocomplete'); | ||
document.body.removeChild(that.sc); | ||
that = null; | ||
} | ||
}; | ||
} | ||
return autoComplete; | ||
})(); | ||
|
||
(function(){ | ||
if (typeof define === 'function' && define.amd) | ||
define('autoComplete', function () { return autoComplete; }); | ||
else if (typeof module !== 'undefined' && module.exports) | ||
module.exports = autoComplete; | ||
else | ||
window.autoComplete = autoComplete; | ||
})(); |
Oops, something went wrong.