← back to Dw Photo Capture
batch mode: vendor is now a dropdown (catalog vendor list) instead of free text
e74d7de94f82ad39bc55e1580b0091a7237c8d42 · 2026-09-18 13:44:47 -0700 · Steve Abrams
Setup made you type the vendor; now it's a <select> populated from /api/vendor-profiles
(181 catalog vendors, sorted) with an 'Other (type it)…' escape for anything not listed.
Falls back to the text field if the profiles fetch fails (offline).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uns3k4K15WBcFJNr3GcUd3
Files touched
Diff
commit e74d7de94f82ad39bc55e1580b0091a7237c8d42
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Sep 18 13:44:47 2026 -0700
batch mode: vendor is now a dropdown (catalog vendor list) instead of free text
Setup made you type the vendor; now it's a <select> populated from /api/vendor-profiles
(181 catalog vendors, sorted) with an 'Other (type it)…' escape for anything not listed.
Falls back to the text field if the profiles fetch fails (offline).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uns3k4K15WBcFJNr3GcUd3
---
public/batch.html | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/public/batch.html b/public/batch.html
index e2edce3..c95c6ca 100644
--- a/public/batch.html
+++ b/public/batch.html
@@ -106,7 +106,8 @@
<h1><b>DW</b> Batch Shoot <span class="ver">__VER__</span></h1>
<p class="sub">Production-line capture — calibrate once, shoot the whole line. Fixed stand + fixed light.</p>
<div class="note">iPad Safari can't hardware-lock white-balance / exposure / focus, so this app <b>software-locks</b>: it stores a calibration frame and checks every shot against it, auto-pausing on drift. No RAW/DNG in a web app — masters are color-corrected JPEGs. Keep the lights fixed and the iPad plugged in.</div>
- <label class="fld"><span>Vendor</span><input id="fVendor" placeholder="Phillip Jeffries" autocapitalize="words"></label>
+ <label class="fld"><span>Vendor</span><select id="fVendorSel"><option value="">— pick vendor —</option><option value="__other__">Other (type it)…</option></select></label>
+ <label class="fld" id="fVendorOtherWrap" hidden><span>Vendor (typed)</span><input id="fVendor" placeholder="Phillip Jeffries" autocapitalize="words"></label>
<label class="fld"><span>Collection</span><input id="fCollection" placeholder="Grasscloth" autocapitalize="words"></label>
<label class="fld"><span>Date</span><input id="fDate" type="date"></label>
<label class="fld"><span>Target count (for the N / count display)</span><input id="fCount" type="number" inputmode="numeric" value="425" min="1"></label>
@@ -292,8 +293,21 @@ $('#fDate').value = new Date().toISOString().slice(0,10);
const last=loadJSON(LS_SESSION,null);
if(last){ $('#bResume').hidden=false; $('#bResume').onclick=()=>{ session=last; enterShoot(); }; }
})();
+// ── vendor dropdown, populated from the catalog vendor profiles (with a type-it escape) ──
+function toggleVendorOther(){ const other=$('#fVendorSel').value==='__other__'; $('#fVendorOtherWrap').hidden=!other; if(other) setTimeout(()=>$('#fVendor').focus(),50); }
+$('#fVendorSel').addEventListener('change', toggleVendorOther);
+(async function loadVendors(){
+ try{
+ const r=await fetch('/api/vendor-profiles'); const d=await r.json();
+ const names=[...new Set([...(d.seeded||[]), ...((d.vendors||[]).map(v=>v&&v.name))])].filter(Boolean).sort((a,b)=>a.localeCompare(b));
+ const sel=$('#fVendorSel'), other=sel.querySelector('option[value="__other__"]');
+ for(const n of names){ const o=document.createElement('option'); o.value=n; o.textContent=n; sel.insertBefore(o,other); }
+ }catch(e){ $('#fVendorSel').value='__other__'; toggleVendorOther(); } // offline → typing still works
+})();
$('#bStart').onclick=()=>{
- const vendor=$('#fVendor').value.trim(), collection=$('#fCollection').value.trim();
+ const vsel=$('#fVendorSel').value;
+ const vendor=(vsel && vsel!=='__other__') ? vsel : $('#fVendor').value.trim();
+ const collection=$('#fCollection').value.trim();
if(!vendor){ toast('Vendor is required'); return; }
const date=$('#fDate').value||new Date().toISOString().slice(0,10);
const id=(vendor+'-'+(collection||'')+'-'+date).replace(/[^A-Za-z0-9._-]+/g,'-').replace(/-+/g,'-').replace(/^-|-$/g,'');
← 0c8c48f Photo capture: vendor picker → sticky overlay bar on the liv
·
back to Dw Photo Capture
·
auto-data-snapshot: 2026-09-18T13:45:34 (2 data files) — dat 37a2682 →