← back to Dw Theme Hamburger
search: add type-ahead predictive dropdown (Shopify /search/suggest.json, product+SKU results as you type)
fc9ece54ed603db1acbfc7483b3ab1f08442b51e · 2026-07-15 10:43:57 -0700 · Steve Abrams
Files touched
M assets/custom.cssM sections/header.liquid
Diff
commit fc9ece54ed603db1acbfc7483b3ab1f08442b51e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 15 10:43:57 2026 -0700
search: add type-ahead predictive dropdown (Shopify /search/suggest.json, product+SKU results as you type)
---
assets/custom.css | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
sections/header.liquid | 59 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/assets/custom.css b/assets/custom.css
index 8ae117b..11da53b 100644
--- a/assets/custom.css
+++ b/assets/custom.css
@@ -1491,6 +1491,63 @@ input.add-to-cart:hover,
pointer-events: auto; /* but the logo itself stays clickable (links home) */
}
+/* ---- Predictive search dropdown (type-ahead SKU/product results) ---- */
+.hdr-suggest {
+ position: fixed;
+ z-index: 4000;
+ background: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.14);
+ border-radius: 4px;
+ box-shadow: 0 10px 34px rgba(0, 0, 0, 0.18);
+ max-height: 74vh;
+ overflow-y: auto;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+}
+.hdr-suggest__row {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 12px;
+ text-decoration: none;
+ color: #141414;
+ border-bottom: 1px solid #f1f1f1;
+}
+.hdr-suggest__row:hover {
+ background: #f7f7f7;
+}
+.hdr-suggest__row img,
+.hdr-suggest__noimg {
+ width: 42px;
+ height: 42px;
+ object-fit: cover;
+ border-radius: 3px;
+ background: #eee;
+ flex: 0 0 42px;
+}
+.hdr-suggest__t {
+ font-size: 13px;
+ line-height: 1.3;
+}
+.hdr-suggest__all {
+ display: block;
+ padding: 11px 12px;
+ font-size: 12px;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+ text-align: center;
+ text-decoration: none;
+ color: #141414;
+ font-weight: 600;
+}
+.hdr-suggest__all:hover {
+ background: #f2f2f2;
+}
+.hdr-suggest__empty {
+ padding: 14px 12px;
+ font-size: 13px;
+ color: #777;
+}
+
/* Right cluster horizontal at ALL widths (theme only made it flex under 1080px,
so search/camera/cart were stacking vertically on desktop) */
.header-content-right--inline-search {
diff --git a/sections/header.liquid b/sections/header.liquid
index 4905611..e0f508b 100644
--- a/sections/header.liquid
+++ b/sections/header.liquid
@@ -350,9 +350,66 @@
if (!toggle) return;
function q() { return wrap.querySelector('.search-form__input'); }
function frm() { return wrap.querySelector('form'); }
+
+ /* ---- predictive dropdown (Shopify native /search/suggest.json) ---- */
+ var box = document.createElement('div');
+ box.className = 'hdr-suggest';
+ box.style.display = 'none';
+ document.body.appendChild(box);
+ var timer = null, lastQ = '';
+ function positionBox() {
+ var input = q(); if (!input) return;
+ var r = input.getBoundingClientRect();
+ box.style.left = Math.max(8, Math.min(r.left, window.innerWidth - 300)) + 'px';
+ box.style.top = (r.bottom + 6) + 'px';
+ box.style.width = Math.max(260, r.width) + 'px';
+ }
+ function hideBox() { box.style.display = 'none'; box.innerHTML = ''; }
+ function render(products, query) {
+ var safeQ = query.replace(/[<>]/g, '');
+ if (!products.length) {
+ box.innerHTML = '<div class="hdr-suggest__empty">No matches for “' + safeQ + '”</div>';
+ } else {
+ box.innerHTML = products.map(function (p) {
+ var img = p.image ? '<img src="' + p.image + '" alt="" loading="lazy">' : '<span class="hdr-suggest__noimg"></span>';
+ return '<a class="hdr-suggest__row" href="' + p.url + '">' + img +
+ '<span class="hdr-suggest__t">' + (p.title || '').replace(/[<>]/g, '') + '</span></a>';
+ }).join('') +
+ '<a class="hdr-suggest__all" href="/search?q=' + encodeURIComponent(query) + '">See all results →</a>';
+ }
+ positionBox();
+ box.style.display = 'block';
+ }
+ function fetchSuggest(query) {
+ var url = '/search/suggest.json?q=' + encodeURIComponent(query) +
+ '&resources[type]=product&resources[limit]=8&resources[options][unavailable_products]=last';
+ fetch(url, { headers: { 'Accept': 'application/json' } })
+ .then(function (r) { return r.json(); })
+ .then(function (d) {
+ if (query !== lastQ) return;
+ var prods = (((d.resources || {}).results || {}).products) || [];
+ render(prods.map(function (p) {
+ return { title: p.title, url: p.url, image: (p.featured_image && p.featured_image.url) || p.image || '' };
+ }), query);
+ }).catch(function () {});
+ }
+ function onInput() {
+ var input = q(); if (!input) return;
+ var val = input.value.trim(); lastQ = val;
+ clearTimeout(timer);
+ if (val.length < 2) { hideBox(); return; }
+ timer = setTimeout(function () { fetchSuggest(val); }, 160);
+ }
+ wrap.addEventListener('input', function (e) {
+ if (e.target && e.target.classList && e.target.classList.contains('search-form__input')) onInput();
+ });
+ window.addEventListener('resize', function () { if (box.style.display === 'block') positionBox(); });
+ window.addEventListener('scroll', function () { if (box.style.display === 'block') positionBox(); }, true);
+
function close() {
wrap.classList.remove('search-open');
toggle.setAttribute('aria-expanded', 'false');
+ hideBox();
}
toggle.addEventListener('click', function (e) {
e.preventDefault();
@@ -367,7 +424,7 @@
if (input) { setTimeout(function () { input.focus(); }, 60); }
});
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
- document.addEventListener('click', function (e) { if (!wrap.contains(e.target)) close(); });
+ document.addEventListener('click', function (e) { if (!wrap.contains(e.target) && !box.contains(e.target)) close(); });
})();
</script>
← 116a2c7 header: tighten hamburger drawer (0.9rem/5px), +top padding
·
back to Dw Theme Hamburger
·
color-palette: hide color-index cards whose image fails to l 9530d81 →