first commit
This commit is contained in:
@@ -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>
|
||||
}
|
||||
Reference in New Issue
Block a user