← back to Customdigitalmurals
sort + density persist to localStorage; hydrate before first grid load
48db47594ef54345c942a7b0f1a7c17ea9187464 · 2026-05-19 15:13:46 -0700 · Steve Abrams
Standing rule: every product grid must persist sort + density selections to
localStorage and rehydrate the saved value before the first grid load. The
storefront had the controls but neither persisted; refresh always reset to
A-Z + density 4. Wires LS_SORT='cdm-sort' + LS_DENSITY='cdm-density' (matches
the existing cdm-theme key style), validates saved values against the rendered
options before applying, and updates the slider DOM value pre-mount so the
first paint matches the user's last choice.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 48db47594ef54345c942a7b0f1a7c17ea9187464
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue May 19 15:13:46 2026 -0700
sort + density persist to localStorage; hydrate before first grid load
Standing rule: every product grid must persist sort + density selections to
localStorage and rehydrate the saved value before the first grid load. The
storefront had the controls but neither persisted; refresh always reset to
A-Z + density 4. Wires LS_SORT='cdm-sort' + LS_DENSITY='cdm-density' (matches
the existing cdm-theme key style), validates saved values against the rendered
options before applying, and updates the slider DOM value pre-mount so the
first paint matches the user's last choice.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
server.js | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/server.js b/server.js
index ffd2742..82bb6da 100644
--- a/server.js
+++ b/server.js
@@ -366,13 +366,13 @@ ${headerHtml('home')}
<option value="">All Studios</option>
</select>
<select id="sort">
- <option value="az">A → Z</option>
- <option value="za">Z → A</option>
+ <option value="az">Title A → Z</option>
+ <option value="za">Title Z → A</option>
<option value="price_asc">Price: Low</option>
<option value="price_desc">Price: High</option>
</select>
<span class="density-label">Density</span>
- <input type="range" id="density" class="density-slider" min="2" max="6" value="4" step="1">
+ <input type="range" id="density" class="density-slider" min="2" max="6" value="4" step="1" aria-label="Grid density">
<span class="count" id="count"></span>
</div>
<div class="grid-wrap">
@@ -392,10 +392,30 @@ ${footerHtml()}
<script>
var page=1, per=60, total=0, pages=0;
var q='', vendor='', sort='az';
+var LS_SORT='cdm-sort', LS_DENSITY='cdm-density';
+
+// Hydrate saved sort + density BEFORE the first grid load.
+try {
+ var savedSort = localStorage.getItem(LS_SORT);
+ if (savedSort) {
+ var sel = document.getElementById('sort');
+ var has = Array.prototype.some.call(sel.options, function(o){ return o.value === savedSort; });
+ if (has) { sort = savedSort; sel.value = savedSort; }
+ }
+} catch(e){}
+
+var savedCols = 4;
+try {
+ var d = parseInt(localStorage.getItem(LS_DENSITY), 10);
+ if (d >= 2 && d <= 6) { savedCols = d; document.getElementById('density').value = String(d); }
+} catch(e){}
function setCols(n){document.querySelector('.product-grid').style.setProperty('--cols',n);}
-document.getElementById('density').addEventListener('input',function(){setCols(+this.value);});
-setCols(4);
+document.getElementById('density').addEventListener('input',function(){
+ setCols(+this.value);
+ try { localStorage.setItem(LS_DENSITY, String(this.value)); } catch(e){}
+});
+setCols(savedCols);
function load(){
var url='/api/products?page='+page+'&per='+per+'&q='+encodeURIComponent(q)+'&vendor='+encodeURIComponent(vendor)+'&sort='+sort;
@@ -446,7 +466,11 @@ fetch('/api/vendors').then(r=>r.json()).then(list=>{
document.getElementById('search').addEventListener('input',function(){q=this.value;page=1;load();});
document.getElementById('vendor-filter').addEventListener('change',function(){vendor=this.value;page=1;load();});
-document.getElementById('sort').addEventListener('change',function(){sort=this.value;page=1;load();});
+document.getElementById('sort').addEventListener('change',function(){
+ sort=this.value;page=1;
+ try { localStorage.setItem(LS_SORT, sort); } catch(e){}
+ load();
+});
load();
</script>
← 917bb01 Phase 2: mobile-ready + tap-to-reveal
·
back to Customdigitalmurals
·
add noreferrer to every target=_blank external link 58420cb →