Obvody/www/js/naseptavac.js

117 lines
3.4 KiB
JavaScript

(function () {
var dataEl = document.getElementById('zvestovatele-data');
var jmena = [];
try {
jmena = JSON.parse(dataEl ? dataEl.textContent || '[]' : '[]');
} catch (e) {
jmena = [];
}
document.querySelectorAll('[data-naseptavac]').forEach(function (root) {
var input = root.querySelector('input');
var nabidka = root.querySelector('.naseptavac-nabidka');
var aktivni = -1;
if (!input || !nabidka) {
return;
}
function klic(text) {
return text.normalize('NFD').replace(/\p{M}/gu, '').toLocaleLowerCase('cs');
}
function shody() {
var dotaz = klic(input.value.trim());
if (dotaz === '') {
return [];
}
var zacina = [];
var obsahuje = [];
jmena.forEach(function (jmeno) {
var pozice = klic(jmeno).indexOf(dotaz);
if (pozice === 0) {
zacina.push(jmeno);
} else if (pozice > 0) {
obsahuje.push(jmeno);
}
});
return zacina.concat(obsahuje).slice(0, 5);
}
function zavri() {
nabidka.hidden = true;
nabidka.replaceChildren();
input.setAttribute('aria-expanded', 'false');
aktivni = -1;
}
function oznac() {
var polozky = nabidka.querySelectorAll('.naseptavac-polozka');
polozky.forEach(function (polozka, index) {
polozka.classList.toggle('is-active', index === aktivni);
});
if (aktivni >= 0 && polozky[aktivni]) {
polozky[aktivni].scrollIntoView({ block: 'nearest' });
}
}
function vykresli() {
var polozky = shody();
nabidka.replaceChildren();
aktivni = -1;
if (!polozky.length) {
zavri();
return;
}
polozky.forEach(function (jmeno) {
var tlacitko = document.createElement('button');
tlacitko.type = 'button';
tlacitko.className = 'naseptavac-polozka';
tlacitko.setAttribute('role', 'option');
tlacitko.textContent = jmeno;
tlacitko.addEventListener('pointerdown', function (event) {
event.preventDefault();
input.value = jmeno;
zavri();
});
nabidka.appendChild(tlacitko);
});
nabidka.hidden = false;
input.setAttribute('aria-expanded', 'true');
}
input.addEventListener('input', vykresli);
input.addEventListener('focus', vykresli);
input.addEventListener('blur', function () {
setTimeout(zavri, 150);
});
input.addEventListener('keydown', function (event) {
var polozky = nabidka.querySelectorAll('.naseptavac-polozka');
if (event.key === 'Escape') {
zavri();
return;
}
if (nabidka.hidden || !polozky.length) {
return;
}
if (event.key === 'ArrowDown') {
event.preventDefault();
aktivni = Math.min(aktivni + 1, polozky.length - 1);
oznac();
} else if (event.key === 'ArrowUp') {
event.preventDefault();
aktivni = Math.max(aktivni - 1, 0);
oznac();
} else if (event.key === 'Enter' && aktivni >= 0) {
event.preventDefault();
input.value = polozky[aktivni].textContent;
zavri();
}
});
});
})();