← back to Glassbeadedwallpaper
glass: make sort+density controls functional
c1d4d44463dab7447e61ea9aaf5a785dbeaa09d2 · 2026-05-27 16:34:56 -0700 · Steve
Two bugs: (1) controls-wiring IIFE ran before #productsGrid was declared so
the density slider + sort listener never bound; (2) even if bound, the sort
change handler was a /* TODO: re-sort live */ no-op. Fixes: added a generic
sortProducts(list,mode) (Newest/Color/Style/SKU/Title) + window.applySort()
that re-renders from the top, deferred the wiring to DOMContentLoaded, and
made loadProducts honor the saved sort (default Newest) instead of always
sorting by color on load. Both controls remain localStorage-persisted.
Files touched
Diff
commit c1d4d44463dab7447e61ea9aaf5a785dbeaa09d2
Author: Steve <steve@designerwallcoverings.com>
Date: Wed May 27 16:34:56 2026 -0700
glass: make sort+density controls functional
Two bugs: (1) controls-wiring IIFE ran before #productsGrid was declared so
the density slider + sort listener never bound; (2) even if bound, the sort
change handler was a /* TODO: re-sort live */ no-op. Fixes: added a generic
sortProducts(list,mode) (Newest/Color/Style/SKU/Title) + window.applySort()
that re-renders from the top, deferred the wiring to DOMContentLoaded, and
made loadProducts honor the saved sort (default Newest) instead of always
sorting by color on load. Both controls remain localStorage-persisted.
---
index.html | 92 ++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 65 insertions(+), 27 deletions(-)
diff --git a/index.html b/index.html
index ec1ddb8..e9be356 100644
--- a/index.html
+++ b/index.html
@@ -370,33 +370,44 @@
<input id="density" type="range" min="180" max="380" step="10" value="240" style="accent-color:var(--accent,#A98B5B);width:140px;cursor:pointer">
</div>
<script>
+// Controls wiring — deferred to DOMContentLoaded so #productsGrid (declared after
+// this block) exists; otherwise getElementById returns null and the density slider
+// + sort listener never bind (controls render but stay inert).
(function(){
- const grid = document.getElementById('productGrid') || document.getElementById('productsGrid');
- const dens = document.getElementById('density');
- const sortSel = document.getElementById('sort');
- const search = document.getElementById('grid-search');
- if (!grid) return;
- const STORE = 'glassbeadedwallpaper_grid';
- const saved = (() => { try { return JSON.parse(localStorage.getItem(STORE) || '{}'); } catch { return {}; } })();
- function applyDensity(v){ grid.style.gridTemplateColumns = 'repeat(auto-fill,minmax(' + v + 'px,1fr))'; }
- if (dens) {
- dens.value = saved.density || 240;
- applyDensity(dens.value);
- dens.addEventListener('input', () => { applyDensity(dens.value); saved.density = dens.value; localStorage.setItem(STORE, JSON.stringify(saved)); });
- }
- if (sortSel) {
- sortSel.value = saved.sort || 'newest';
- sortSel.addEventListener('change', () => { saved.sort = sortSel.value; localStorage.setItem(STORE, JSON.stringify(saved)); /* TODO: re-sort live */ });
- }
- if (search) {
- search.addEventListener('input', () => {
- const q = search.value.toLowerCase().trim();
- Array.from(grid.children).forEach(card => {
- const t = (card.textContent || '').toLowerCase();
- card.style.display = !q || t.includes(q) ? '' : 'none';
+ function wire(){
+ const grid = document.getElementById('productGrid') || document.getElementById('productsGrid');
+ const dens = document.getElementById('density');
+ const sortSel = document.getElementById('sort');
+ const search = document.getElementById('grid-search');
+ if (!grid) return;
+ const STORE = 'glassbeadedwallpaper_grid';
+ const saved = (() => { try { return JSON.parse(localStorage.getItem(STORE) || '{}'); } catch { return {}; } })();
+ function applyDensity(v){ grid.style.gridTemplateColumns = 'repeat(auto-fill,minmax(' + v + 'px,1fr))'; }
+ if (dens) {
+ dens.value = saved.density || 240;
+ applyDensity(dens.value);
+ dens.addEventListener('input', () => { applyDensity(dens.value); saved.density = dens.value; localStorage.setItem(STORE, JSON.stringify(saved)); });
+ }
+ if (sortSel) {
+ sortSel.value = saved.sort || 'newest';
+ sortSel.addEventListener('change', () => {
+ saved.sort = sortSel.value;
+ localStorage.setItem(STORE, JSON.stringify(saved));
+ if (typeof window.applySort === 'function') window.applySort(sortSel.value);
});
- });
+ }
+ if (search) {
+ search.addEventListener('input', () => {
+ const q = search.value.toLowerCase().trim();
+ Array.from(grid.children).forEach(card => {
+ const t = (card.textContent || '').toLowerCase();
+ card.style.display = !q || t.includes(q) ? '' : 'none';
+ });
+ });
+ }
}
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', wire);
+ else wire();
})();
</script>
@@ -538,6 +549,31 @@
});
}
+ // Generic multi-mode sort (Newest/Color/Style/SKU/Title) for the sort <select>.
+ function sortProducts(list, mode) {
+ const arr = [...list];
+ const sku = p => (p.primarySku || p.handle || '').toLowerCase();
+ const title = p => (p.title || '').toLowerCase();
+ const style = p => ((p.tags && p.tags[0]) || p.category || p.productType || '~').toLowerCase();
+ switch (mode) {
+ case 'color': return sortProductsByColor(arr);
+ case 'style': arr.sort((a, b) => style(a).localeCompare(style(b)) || title(a).localeCompare(title(b))); break;
+ case 'sku': arr.sort((a, b) => sku(a).localeCompare(sku(b))); break;
+ case 'title': arr.sort((a, b) => title(a).localeCompare(title(b))); break;
+ case 'newest': default: arr.sort((a, b) => new Date(b.createdAt || 0) - new Date(a.createdAt || 0)); break;
+ }
+ return arr;
+ }
+
+ // Re-sort the current (possibly color-filtered) set and re-render from the top.
+ window.applySort = function (mode) {
+ filteredProducts = sortProducts(filteredProducts, mode);
+ displayedProducts = 0;
+ const grid = document.getElementById('productsGrid');
+ if (grid) grid.innerHTML = '';
+ displayBatch();
+ };
+
async function loadProducts() {
const grid = document.getElementById('productsGrid');
console.log('Loading glass beaded products...');
@@ -557,11 +593,13 @@
console.log(`✓ Loaded ${allProducts.length} glass beaded products`);
- // Sort products by color on load
+ // Apply saved sort on load (default Newest per hard-rule), not always-color.
try {
- allProducts = sortProductsByColor(allProducts);
+ let savedSort = 'newest';
+ try { savedSort = (JSON.parse(localStorage.getItem('glassbeadedwallpaper_grid') || '{}').sort) || 'newest'; } catch {}
+ allProducts = sortProducts(allProducts, savedSort);
filteredProducts = allProducts;
- console.log('Products sorted by color');
+ console.log('Products sorted by', savedSort);
} catch (err) {
console.error('Error sorting products:', err);
}
← 19eb646 redact vendor names from customer-facing /api (close fleet l
·
back to Glassbeadedwallpaper
·
gitignore: add backup/orig/old file patterns to prevent sour a5f7d52 →