Make whole battery row open the timeline modal; drop the shop link from the row

This commit is contained in:
Michiel Berger 2026-05-01 09:23:54 +02:00
parent b39501ca21
commit be6012c1ea
3 changed files with 24 additions and 20 deletions

View file

@ -106,17 +106,10 @@ function renderTable(rows) {
tbody.replaceChildren();
rows.forEach((r, i) => {
const tr = el("tr");
if (r.category) tr.dataset.category = r.category;
if (r.url) tr.dataset.url = r.url; // kept for the modal header, not the row link
tr.append(td(String(i + 1)));
// Title cell — anchor with safe text.
const tdTitle = el("td");
if (r.url) {
const a = el("a", { href: r.url, target: "_blank", rel: "noopener", text: r.title });
tdTitle.appendChild(a);
} else {
tdTitle.textContent = r.title;
}
tr.appendChild(tdTitle);
tr.append(td(r.title));
const tenYrCls = r.ten_year_profit_eur < 0 ? "neg" : "pos";
tr.append(
@ -215,11 +208,10 @@ function captureInitialFromDOM() {
const rows = Array.from(tbody.querySelectorAll("tr"));
lastBatteries = rows.map((tr) => {
const cells = tr.children;
const link = cells[1].querySelector("a");
return {
category: tr.dataset.category || null,
title: (link ? link.textContent : cells[1].textContent).trim(),
url: link ? link.href : "",
title: cells[1].textContent.trim(),
url: tr.dataset.url || "",
capacity_kwh: parseFloat(cells[2].textContent),
power_kw: parseFloat(cells[3].textContent),
price_eur: parseFloat(cells[4].textContent.replace("€", "")),
@ -274,7 +266,19 @@ let charts = { irr: null, soc: null, grid: null };
function openModalForBattery(row) {
activeBattery = row;
tlTitle.textContent = `${row.title}${fmtNum(row.capacity_kwh)} kWh / ${fmtNum(row.power_kw, 1)} kW`;
tlTitle.replaceChildren();
tlTitle.appendChild(document.createTextNode(
`${row.title}${fmtNum(row.capacity_kwh)} kWh / ${fmtNum(row.power_kw, 1)} kW`,
));
if (row.url) {
const a = document.createElement("a");
a.href = row.url;
a.target = "_blank";
a.rel = "noopener";
a.textContent = "view on store ↗";
a.className = "shop-link";
tlTitle.appendChild(a);
}
if (!tlDate.value) tlDate.value = "2025-06-15";
modal.hidden = false;
refreshTimeline();
@ -423,8 +427,6 @@ function drawChart(key, axes, xs, ys, containerId, opts = {}) {
// Hook up battery row clicks.
tbody.addEventListener("click", (e) => {
// Ignore link clicks — let those go to the shop page if user explicitly wants it.
if (e.target.closest("a")) return;
const tr = e.target.closest("tr");
if (!tr) return;
const idx = Array.from(tbody.children).indexOf(tr);

View file

@ -218,6 +218,8 @@ table#leaderboard tbody tr a { color: inherit; text-decoration: underline dotted
.modal-card header { display: flex; justify-content: space-between;
align-items: baseline; margin-bottom: 0.75rem; }
.modal-card h2 { margin: 0; font-size: 1.1rem; }
.modal-card h2 .shop-link { font-size: 0.75rem; font-weight: 400; margin-left: 0.75rem; color: var(--muted); }
.modal-card h2 .shop-link:hover { color: var(--link); }
.modal-close { background: none; border: 0; font-size: 1.6rem; line-height: 1;
color: var(--muted); cursor: pointer; padding: 0 0.5rem; }
.modal-close:hover { color: var(--text); }

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Honest battery payback — vs thuisbatterijgids.nl</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uplot@1.6.31/dist/uPlot.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}?v=16">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}?v=17">
</head>
<body>
@ -114,9 +114,9 @@
</thead>
<tbody id="leaderboard-body">{# rendered cells start below; legend follows the table. #}
{% for r in initial.batteries %}
<tr data-category="{{ r.category }}">
<tr data-category="{{ r.category }}" data-url="{{ r.url }}">
<td>{{ loop.index }}</td>
<td><a href="{{ r.url }}" target="_blank" rel="noopener">{{ r.title }}</a></td>
<td>{{ r.title }}</td>
<td>{{ '%.2f' % r.capacity_kwh }}</td>
<td>{{ '%.1f' % r.power_kw }}</td>
<td>€{{ '%.0f' % r.price_eur }}</td>
@ -157,7 +157,7 @@
</footer>
<script src="https://cdn.jsdelivr.net/npm/uplot@1.6.31/dist/uPlot.iife.min.js"></script>
<script src="{{ url_for('static', filename='app.js') }}?v=16"></script>
<script src="{{ url_for('static', filename='app.js') }}?v=17"></script>
<div id="timeline-modal" class="modal" hidden>
<div class="modal-backdrop" data-close="modal"></div>