Fix price chart destroyed by LiveView DOM patches on filter change

LiveView's morphdom was replacing the canvas element inside the chart
container whenever filters were toggled, destroying the Chart.js
rendering context. Add phx-update="ignore" to the chart container so
LiveView preserves JS-managed children after initial render.
This commit is contained in:
Graham McIntire 2026-03-13 13:38:45 -05:00
parent fd907c40cb
commit f075ab55fb
No known key found for this signature in database
2 changed files with 17 additions and 0 deletions

View file

@ -282,6 +282,7 @@ defmodule AmmopricesWeb.CaliberLive.Show do
<div
id="price-chart-container"
phx-hook=".PriceChart"
phx-update="ignore"
data-chart-data={Jason.encode!(@chart_data)}
class="h-64 sm:h-80"
>

View file

@ -182,6 +182,22 @@ defmodule AmmopricesWeb.CaliberLive.ShowTest do
assert has_element?(view, "#filter-casing-steel")
end
test "chart container uses phx-update=ignore to survive DOM patches", %{
conn: conn,
caliber: caliber,
retailer: retailer
} do
now = DateTime.truncate(DateTime.utc_now(), :second)
product = product_fixture(%{caliber: caliber, retailer: retailer, grain_weight: 115, in_stock: true})
snapshot_fixture(%{product: product, price_per_round_cents: 28, in_stock: true, recorded_at: now})
{:ok, view, _html} = live(conn, "/calibers/#{caliber.slug}")
# Chart container must have phx-update="ignore" so LiveView
# does not replace the canvas element managed by Chart.js
assert has_element?(view, "#price-chart-container[phx-update=ignore]")
end
test "receives real-time price updates via PubSub", %{conn: conn, caliber: caliber, retailer: retailer} do
now = DateTime.truncate(DateTime.utc_now(), :second)
product = product_fixture(%{caliber: caliber, retailer: retailer, in_stock: true})