first commit

This commit is contained in:
Matthias Hinrichs
2025-07-05 03:10:41 +02:00
commit 9b7bdcbc53
39 changed files with 5109 additions and 0 deletions
@@ -0,0 +1,89 @@
package components
templ SearchJS() {
<script>
const input = document.getElementById('stock-search-input');
const dropdown = document.getElementById('search-dropdown');
let debounceTimeout;
let selectedIndex = -1;
input.addEventListener('input', function () {
selectedIndex = -1;
const query = input.value.trim();
clearTimeout(debounceTimeout);
if (query.length < 2) {
dropdown.classList.remove('show');
dropdown.innerHTML = '';
return;
}
debounceTimeout = setTimeout(() => {
fetch('/api/stocksearch?q=' + encodeURIComponent(query))
.then(res => res.json())
.then(data => {
if (data.quotes && data.quotes.length > 0) {
dropdown.innerHTML = data.quotes.map(item =>
`<a class="dropdown-item-search" href="/details?stock=${encodeURIComponent(item.symbol)}">${item.longname || item.shortname || item.symbol} (${item.symbol})</a>`
).join('');
dropdown.classList.add('show');
} else {
dropdown.innerHTML = '<div class="dropdown-item-search">Keine Ergebnisse</div>';
dropdown.classList.add('show');
}
});
}, 300);
});
input.addEventListener('keydown', function (e) {
const items = Array.from(dropdown.querySelectorAll('.dropdown-item-search'));
if (!dropdown.classList.contains('show') || items.length === 0) return;
if (e.key === 'ArrowDown') {
e.preventDefault();
selectedIndex = (selectedIndex + 1) % items.length;
updateDropdownSelection(items);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
selectedIndex = (selectedIndex - 1 + items.length) % items.length;
updateDropdownSelection(items);
} else if (e.key === 'Enter') {
if (selectedIndex >= 0 && selectedIndex < items.length) {
e.preventDefault();
window.location.href = items[selectedIndex].getAttribute('href');
}
}
});
function updateDropdownSelection(items) {
items.forEach((item, idx) => {
if (idx === selectedIndex) {
item.classList.add('active');
item.scrollIntoView({ block: 'nearest' });
} else {
item.classList.remove('active');
}
});
}
document.addEventListener('click', function (e) {
if (!input.contains(e.target) && !dropdown.contains(e.target)) {
dropdown.classList.remove('show');
}
});
document.getElementById('stock-search-form').addEventListener('submit', function(e) {
e.preventDefault();
const items = Array.from(dropdown.querySelectorAll('.dropdown-item-search'));
// Wenn ein Eintrag ausgewählt ist, nimm diesen
if (selectedIndex >= 0 && selectedIndex < items.length) {
window.location.href = items[selectedIndex].getAttribute('href');
return;
}
// Sonst nimm das erste Ergebnis, falls vorhanden
if (items.length > 0) {
window.location.href = items[0].getAttribute('href');
return;
}
// Sonst nichts tun
});
</script>
}