Skip to content
Snippets Groups Projects
Commit 443b5823 authored by Jiří Setnička's avatar Jiří Setnička Committed by Martin Mareš
Browse files

JS autocomplete pro inputy

Umí jako parametr vzít pole stringů nebo pole dvojic [klíč, text], při vybrání
podporuje callback.
parent ee6152fa
No related branches found
No related tags found
No related merge requests found
...@@ -116,6 +116,7 @@ app.assets.add_assets([ ...@@ -116,6 +116,7 @@ app.assets.add_assets([
'mo.css', 'mo.css',
'js/news-reloader.js', 'js/news-reloader.js',
'js/osmo.js', 'js/osmo.js',
'js/autocomplete.js'
]) ])
... ...
......
// Adapted from https://www.w3schools.com/howto/howto_js_autocomplete.asp
function autocomplete(inp, arr, callback=null, max=10) {
var currentFocus;
var listCount;
function do_autocomplete(e) {
var a, b, i, val = this.value;
closeAllLists();
currentFocus = -1;
a = document.createElement("DIV");
a.setAttribute("id", this.id + "autocomplete-list");
a.setAttribute("class", "autocomplete-items");
this.parentNode.appendChild(a);
listCount = 0;
for (i = 0; i < arr.length; i++) {
var key, text;
if (Array.isArray(arr[i])) {
key = arr[i][0]; text = arr[i][1];
} else {
key = arr[i]; text = arr[i];
}
/*check if the item starts with the same letters as the text field value:*/
//if (text.substr(0, val.length).toUpperCase() == val.toUpperCase()) {
index = text.toUpperCase().indexOf(val.toUpperCase());
if (index != -1) {
listCount++;
b = document.createElement("DIV");
b.innerHTML = text.substr(0, index) + "<strong>" + text.substr(index, val.length) + "</strong>" + text.substr(index + val.length)
b.innerHTML += "<input type='hidden' value='" + key + "'>";
b.innerHTML += "<input type='hidden' value='" + text + "'>";
b.addEventListener("click", function(e) {
key = this.getElementsByTagName("input")[0].value;
text = this.getElementsByTagName("input")[1].value;
inp.value = text;
if (callback) {
callback(key);
}
closeAllLists();
});
a.appendChild(b);
}
if (listCount == max) break;
}
};
inp.addEventListener("input", do_autocomplete);
inp.addEventListener("focus", do_autocomplete);
inp.addEventListener("keydown", function(e) {
var x = document.getElementById(this.id + "autocomplete-list");
if (x) x = x.getElementsByTagName("div");
if (e.keyCode == 40) { // arrow down
currentFocus++;
addActive(x);
} else if (e.keyCode == 38) { // arrow up
currentFocus--;
addActive(x);
} else if (e.keyCode == 13) { // enter
e.preventDefault(); // do not submit the form
if (currentFocus == -1 && listCount > 0) {
currentFocus++;
}
if (currentFocus > -1) {
if (x) x[currentFocus].click(); // simulate a click on the "active" item
}
} else if (e.keyCode == 27) { // escape
inp.blur();
closeAllLists();
}
e.stopPropagation();
});
function addActive(x) {
if (!x) return false;
removeActive(x);
if (currentFocus >= x.length) currentFocus = 0;
if (currentFocus < 0) currentFocus = (x.length - 1);
x[currentFocus].classList.add("autocomplete-active");
}
function removeActive(x) {
for (var i = 0; i < x.length; i++) {
x[i].classList.remove("autocomplete-active");
}
}
function closeAllLists(elmnt) {
/* close all autocomplete lists in the document, except the one passed as an argument: */
var x = document.getElementsByClassName("autocomplete-items");
for (var i = 0; i < x.length; i++) {
if (elmnt != x[i] && elmnt != inp && (!elmnt || elmnt.parentNode != x[i].parentNode)) {
x[i].parentNode.removeChild(x[i]);
}
}
}
// close all autocomplete lists when clicked elsewhere
document.addEventListener("click", function (e) {
closeAllLists(e.target);
});
}
function closeAllAutocomplete() {
var x = document.getElementsByClassName("autocomplete-items");
for (var i = 0; i < x.length; i++) {
x[i].parentNode.removeChild(x[i]);
}
}
...@@ -408,3 +408,35 @@ div.message .msg-date { ...@@ -408,3 +408,35 @@ div.message .msg-date {
font-style: italic; font-style: italic;
color: #777; color: #777;
} }
/* Autocomplete for inputs */
.autocomplete {
position: relative;
display: inline-block;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/* position the autocomplete items to be the same width as the container */
top: 100%;
left: 0;
right: 0;
margin: 0px 15px;
}
.autocomplete-items div {
padding: 5px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
.autocomplete-items div:hover {
background-color: #e9e9e9;
}
.autocomplete-active {
background-color: DodgerBlue !important;
color: #ffffff;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment