File: D:/web/hyperflight/2026-07-23/prev/inc-template-search.asp
<%
' --- START OF SEARCH TEMPLATES --- '
' (SS,17/1/13) added ending / to input tag of cbsubcat
' (SS,13/8/14) bootstrap version
' (SS,1/3/14) replaced form tags with div (because there's already the frmSearch form outside this,
' had to adjust padding and margin and add margin-top of 10px to make it behave as before
' (SS,30/6/17) added value = ASearchDefault
' (SS,21/5/26) Bootstrap 5 version for HyperFlight
' (SS,20/7/26) change to placeholder text from "Search..." to "Search products..."
' (SS,21/7/26) modified for incremental search
Sub ShowSearchMain(ASearchDefault, ASelectComboHTML)
%>
<!-- START OF SEARCH -->
<div class="header-search-wrapper">
<div class="header-search-form">
<div class="input-group">
<input type="hidden" name="cbsubcat" value="">
<input type="search"
class="form-control rounded-start"
placeholder="Search products..."
name="search"
id="search"
value="<%=ASearchDefault%>"
aria-label="Search"
autocomplete="off"
spellcheck="false">
<button class="btn btn-outline-secondary rounded-end"
type="button"
onclick="itp_search()"
aria-label="Search">
<i class="fa-regular fa-magnifying-glass" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="search-suggest-panel" hidden></div>
</div>
<%
AddScript("ScriptSearchSuggest")
End Sub
' (SS,21/7/26)
Sub ScriptSearchSuggest
%>
<script>
document.addEventListener('DOMContentLoaded', function () {
const wrappers = document.querySelectorAll('.header-search-wrapper');
wrappers.forEach(function (wrapper) {
const input = wrapper.querySelector('input[name="search"]');
const panel = wrapper.querySelector('.search-suggest-panel');
if (!input || !panel) return;
let timer = null;
let controller = null;
function hidePanel() {
panel.hidden = true;
panel.innerHTML = '';
}
input.addEventListener('input', function () {
const q = input.value.trim();
clearTimeout(timer);
if (q.length < 3) {
hidePanel();
return;
}
timer = setTimeout(function () {
if (controller) {
controller.abort();
}
controller = new AbortController();
fetch('/ajax.asp?cmd=product_search_suggest&q=' + encodeURIComponent(q), {
signal: controller.signal,
headers: {
'X-Requested-With': 'fetch'
}
})
.then(function (response) {
if (!response.ok) {
throw new Error('Search suggest failed');
}
return response.text();
})
.then(function (html) {
/* Ignore stale results if the user has typed more since this request started */
if (input.value.trim() !== q) return;
html = html.trim();
if (html === '') {
hidePanel();
} else {
panel.innerHTML = html;
panel.hidden = false;
}
})
.catch(function (err) {
if (err.name === 'AbortError') return;
hidePanel();
});
}, 275);
});
input.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
hidePanel();
}
});
document.addEventListener('click', function (event) {
if (!wrapper.contains(event.target)) {
panel.hidden = true;
}
});
});
});
</script>
<%
End Sub
' --- END OF SEARCH TEMPLATES --- '
ShowSearch
%>