← back to Nationalrealestate
USRE grid: CSV export honors active filters — export filtered+sorted rows client-side (was dumping ALL rows) (v0.7.0)
966b6289d0711426b5902b83016ce0b83a3399e9 · 2026-07-26 19:57:46 -0700 · Steve
Files touched
M package-lock.jsonM package.jsonM public/crcp-grid.jsM public/markets.html
Diff
commit 966b6289d0711426b5902b83016ce0b83a3399e9
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jul 26 19:57:46 2026 -0700
USRE grid: CSV export honors active filters — export filtered+sorted rows client-side (was dumping ALL rows) (v0.7.0)
---
package-lock.json | 4 ++--
package.json | 2 +-
public/crcp-grid.js | 29 ++++++++++++++++++++++++++++-
public/markets.html | 8 ++++++++
4 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 7aefdd2..a3d5d85 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "nationalrealestate",
- "version": "0.6.0",
+ "version": "0.7.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "nationalrealestate",
- "version": "0.6.0",
+ "version": "0.7.0",
"dependencies": {
"better-sqlite3": "^13.0.1",
"dotenv": "^16.4.5",
diff --git a/package.json b/package.json
index fb69a74..c6b2c3c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "nationalrealestate",
- "version": "0.6.0",
+ "version": "0.7.0",
"private": true,
"type": "module",
"description": "USRealEstate — national U.S. residential market explorer. Free-data v1 (Redfin Data Center, Zillow Research, Census ACS, FHFA). Internal analyst tool behind basic auth.",
diff --git a/public/crcp-grid.js b/public/crcp-grid.js
index d68eff5..a7a36dd 100644
--- a/public/crcp-grid.js
+++ b/public/crcp-grid.js
@@ -299,8 +299,35 @@
});
}
+ // Export the CURRENTLY filtered + sorted rows (uncapped) as a CSV Blob — so a
+ // download reflects exactly what the user filtered to, not the whole dataset.
+ function exportCSV(opts) {
+ opts = opts || {};
+ const rows = sortRows(data.filter(pass));
+ const cols = fields.filter(f => !f.badge && f.k !== 'name'); // 'name' handled as the title column
+ const csvEsc = v => { if (v == null) return ''; v = String(v); return /[",\n]/.test(v) ? '"' + v.replace(/"/g, '""') + '"' : v; };
+ const header = ['Name'].concat(cols.map(f => f.l));
+ const lines = [header.map(csvEsc).join(',')];
+ rows.forEach(r => {
+ const t = O.title ? O.title(r) : { name: r.name || '' };
+ lines.push([csvEsc(t.name)].concat(cols.map(f => csvEsc(fval(r, f)))).join(','));
+ });
+ const blob = new Blob([lines.join('\n')], { type: 'text/csv;charset=utf-8' });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url; a.download = opts.filename || 'export.csv';
+ document.body.appendChild(a); a.click(); a.remove();
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
+ return rows.length;
+ }
+
buildTop(); buildRail(); render();
- return { render, setData(d) { O.data.length = 0; d.forEach(x => O.data.push(x)); buildRail(); render(); } };
+ return {
+ render,
+ setData(d) { O.data.length = 0; d.forEach(x => O.data.push(x)); buildRail(); render(); },
+ exportCSV,
+ filteredCount() { return data.filter(pass).length; },
+ };
}
global.CrcpGrid = { mount: opts => new CrcpGrid(opts) };
diff --git a/public/markets.html b/public/markets.html
index a82d865..b61ab53 100644
--- a/public/markets.html
+++ b/public/markets.html
@@ -151,6 +151,14 @@ document.getElementById('typeSeg').addEventListener('click', e => {
const b = e.target.closest('button[data-type]');
if (b && b.dataset.type !== TYPE) load(b.dataset.type);
});
+// CSV export now honors the active filters — export the grid's filtered+sorted rows
+// client-side instead of hitting the server endpoint (which dumps ALL rows).
+document.getElementById('exportcsv').addEventListener('click', e => {
+ if (!grid) return; // fall back to the href if the grid isn't ready
+ e.preventDefault();
+ const n = grid.exportCSV({ filename: `usre-markets-${TYPE}.csv` });
+ console.log(`exported ${n} filtered ${TYPE} rows`);
+});
load(TYPE);
</script>
<script src="/nav-drawer.js"></script>
← 6e08a2b auto-save: 2026-07-26T17:14:46 (2 files) — src/ingest/parcel
·
back to Nationalrealestate
·
USRE grid: polished empty state — icon + message + one-click 46b0b58 →