Files
orderPRO/public/assets/js/modules/global-search.js
2026-04-07 20:32:43 +02:00

125 lines
3.5 KiB
JavaScript

(function () {
'use strict';
var input = document.getElementById('js-global-search');
var resultsEl = document.getElementById('js-global-search-results');
if (!input || !resultsEl) return;
var debounceTimer = null;
var highlightIndex = -1;
var currentResults = [];
function escapeHtml(str) {
var div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
function closeResults() {
resultsEl.innerHTML = '';
resultsEl.style.display = 'none';
highlightIndex = -1;
currentResults = [];
}
function renderResults(results) {
currentResults = results;
highlightIndex = -1;
if (results.length === 0) {
resultsEl.innerHTML = '<div class="global-search__empty">Brak wyników</div>';
resultsEl.style.display = 'block';
return;
}
var html = '';
for (var i = 0; i < results.length; i++) {
var r = results[i];
var details = [];
if (r.buyer_name) details.push(escapeHtml(r.buyer_name));
if (r.buyer_email) details.push(escapeHtml(r.buyer_email));
if (r.buyer_phone) details.push(escapeHtml(r.buyer_phone));
html += '<a href="/orders/' + r.id + '" class="global-search__item" data-index="' + i + '">'
+ '<div class="global-search__item-title">' + escapeHtml(r.order_number || '-') + '</div>'
+ '<div class="global-search__item-details">' + details.join(' | ') + '</div>'
+ '</a>';
}
resultsEl.innerHTML = html;
resultsEl.style.display = 'block';
}
function updateHighlight() {
var items = resultsEl.querySelectorAll('.global-search__item');
for (var i = 0; i < items.length; i++) {
if (i === highlightIndex) {
items[i].classList.add('is-highlighted');
items[i].scrollIntoView({ block: 'nearest' });
} else {
items[i].classList.remove('is-highlighted');
}
}
}
function doSearch(query) {
fetch('/api/orders/search?q=' + encodeURIComponent(query) + '&limit=10', {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
})
.then(function (resp) { return resp.json(); })
.then(function (data) {
if (input.value.trim().length < 2) {
closeResults();
return;
}
renderResults(data.results || []);
})
.catch(function () {
closeResults();
});
}
input.addEventListener('input', function () {
var query = input.value.trim();
clearTimeout(debounceTimer);
if (query.length < 2) {
closeResults();
return;
}
debounceTimer = setTimeout(function () {
doSearch(query);
}, 300);
});
input.addEventListener('keydown', function (e) {
if (currentResults.length === 0) return;
if (e.key === 'ArrowDown') {
e.preventDefault();
highlightIndex = Math.min(highlightIndex + 1, currentResults.length - 1);
updateHighlight();
} else if (e.key === 'ArrowUp') {
e.preventDefault();
highlightIndex = Math.max(highlightIndex - 1, 0);
updateHighlight();
} else if (e.key === 'Enter') {
e.preventDefault();
if (highlightIndex >= 0 && highlightIndex < currentResults.length) {
window.location.href = '/orders/' + currentResults[highlightIndex].id;
}
} else if (e.key === 'Escape') {
closeResults();
input.blur();
}
});
document.addEventListener('click', function (e) {
var wrap = document.getElementById('js-global-search-wrap');
if (wrap && !wrap.contains(e.target)) {
closeResults();
}
});
})();