← back to Rentv 2026
News map: add From/To year-range filter (2015-present)
7ac0a3d5b1445cbe98143b1fc8e2c232c8c15eaf · 2026-08-06 09:12:23 -0700 · Steve Abrams
Makes the 11-year archive navigable — scope pins + list to any year span. Wired
into passFilter (composes with freshness + type filters); Reset restores full range.
TK-10284
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit 7ac0a3d5b1445cbe98143b1fc8e2c232c8c15eaf
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Aug 6 09:12:23 2026 -0700
News map: add From/To year-range filter (2015-present)
Makes the 11-year archive navigable — scope pins + list to any year span. Wired
into passFilter (composes with freshness + type filters); Reset restores full range.
TK-10284
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
public/map.html | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/public/map.html b/public/map.html
index 4f2e02af..2956a25e 100644
--- a/public/map.html
+++ b/public/map.html
@@ -71,6 +71,12 @@ aside .ah{padding:12px 16px;border-bottom:1px solid var(--line);font-size:12px;f
<label>Type
<select id="txn"><option value="">All</option></select>
</label>
+ <label>Years
+ <select id="yfrom" title="From year"></select>
+ </label>
+ <label style="margin-left:-8px">–
+ <select id="yto" title="To year"></select>
+ </label>
<button class="btn" id="near">📍 Near me</button>
<button class="btn ghost" id="reset">Reset view</button>
</div></div>
@@ -113,7 +119,7 @@ setTimeout(function(){map.invalidateSize();},200);
window.addEventListener('resize',function(){map.invalidateSize();});
var ALL=[], markers=[], meMarker=null, meLatLng=null;
-var fFresh='all', fTxn='';
+var fFresh='all', fTxn='', fYFrom=0, fYTo=9999;
function popupHtml(a){
var meta=[a.city+(a.state?', '+a.state:''), a.txn, a.ptype, a.amt].filter(Boolean).join(' · ');
@@ -125,6 +131,8 @@ function passFilter(a){
if(fFresh==='new' && !a._fresh) return false;
if(fFresh==='old' && a._fresh) return false;
if(fTxn && a.txn!==fTxn) return false;
+ var y=parseInt((a.date||'').slice(0,4),10)||0;
+ if(y && (y<fYFrom || y>fYTo)) return false;
return true;
}
function buildMarkers(){
@@ -192,7 +200,10 @@ map.on('moveend',function(){ if(!meLatLng) refreshList(); });
$('fresh').onchange=function(e){fFresh=e.target.value;buildMarkers();};
$('txn').onchange=function(e){fTxn=e.target.value;buildMarkers();};
$('reset').onclick=function(){ meLatLng=null; if(meMarker){map.removeLayer(meMarker);meMarker=null;}
- map.setView([37.5,-119],5); refreshList(); };
+ fFresh='all';$('fresh').value='all'; fTxn='';$('txn').value='';
+ if($('yfrom').options.length){fYFrom=parseInt($('yfrom').options[$('yfrom').options.length-1].value,10);$('yfrom').value=fYFrom;
+ fYTo=parseInt($('yto').options[0].value,10);$('yto').value=fYTo;}
+ map.setView([37.5,-119],5); buildMarkers(); };
$('near').onclick=function(){
if(!navigator.geolocation){alert('Location isn’t available in this browser.');return;}
$('near').textContent='📍 Locating…';
@@ -214,6 +225,17 @@ fetch('/api/map-articles').then(function(r){return r.json();}).then(function(d){
// populate txn filter from data
var txns={}; ALL.forEach(function(a){if(a.txn)txns[a.txn]=1;});
Object.keys(txns).sort().forEach(function(t){var o=document.createElement('option');o.value=t;o.textContent=t;$('txn').appendChild(o);});
+ // populate year range from data (spans ~2015..present)
+ var yrs=ALL.map(function(a){return parseInt((a.date||'').slice(0,4),10)||0;}).filter(Boolean);
+ var yMin=Math.min.apply(null,yrs), yMax=Math.max.apply(null,yrs);
+ fYFrom=yMin; fYTo=yMax;
+ for(var y=yMax;y>=yMin;y--){
+ var of=document.createElement('option'); of.value=y; of.textContent=y; $('yfrom').appendChild(of);
+ var ot=document.createElement('option'); ot.value=y; ot.textContent=y; $('yto').appendChild(ot);
+ }
+ $('yfrom').value=yMin; $('yto').value=yMax;
+ $('yfrom').onchange=function(e){fYFrom=parseInt(e.target.value,10); if(fYFrom>fYTo){fYTo=fYFrom;$('yto').value=fYTo;} buildMarkers();};
+ $('yto').onchange=function(e){fYTo=parseInt(e.target.value,10); if(fYTo<fYFrom){fYFrom=fYTo;$('yfrom').value=fYFrom;} buildMarkers();};
if(!ALL.length){ $('list').innerHTML='<p class="empty">The map data is still building. Check back shortly.</p>'; return; }
buildMarkers();
}).catch(function(){ $('list').innerHTML='<p class="empty">The map is temporarily unavailable.</p>'; });
← 10ac233d harden(deals/closings): Cody gate — word-boundary match for
·
back to Rentv 2026
·
PR intel: Gmail correspondence sync + per-contact timeline 0884d55a →