Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace horsey with Pixabay's autocomplete #75

Merged
merged 1 commit into from
Sep 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions layouts/partials/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<link href="{{"css/hybrid.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
<link href="{{"css/featherlight.min.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
<link href="{{"css/perfect-scrollbar.min.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
<link href="{{"css/horsey.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
<link href="{{"css/auto-complete.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
<link href="{{"css/theme.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
<link href="{{"css/hugo-theme.css" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}" rel="stylesheet">
{{with .Site.Params.themeVariant}}
Expand Down Expand Up @@ -92,4 +92,4 @@ <h1>{{.Title}}</h1>
{{else}}
{{.value|safeHTML}}
{{end}}
{{end}}
{{end}}
2 changes: 1 addition & 1 deletion layouts/partials/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
{{ $assetBusting := not .Site.Params.disableAssetsBusting }}
<script type="text/javascript" src="{{"js/lunr.min.js" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}"></script>
<script type="text/javascript" src="{{"js/horsey.js" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}"></script>
<script type="text/javascript" src="{{"js/auto-complete.js" | relURL}}{{ if $assetBusting }}?{{ now.Unix }}{{ end }}"></script>
<script type="text/javascript">
{{ if .Site.IsMultiLingual }}
var baseurl = "{{.Site.BaseURL}}{{.Site.LanguagePrefix}}";
Expand Down
47 changes: 47 additions & 0 deletions static/css/auto-complete.css
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;
}
35 changes: 0 additions & 35 deletions static/css/horsey.css

This file was deleted.

223 changes: 223 additions & 0 deletions static/js/auto-complete.js
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;
})();
Loading