The panel that closed itself

Projectselixir liveview

I made it so posts can live in multiple spaces: An “Also show in” panel of checkboxes lets it appear in others. A lot of checkboxes is a lot of form, so that added complexity.

<details class="post-form__also-interests">
  <summary><%= t("Also show in") %></summary>
  <div class="post-form__also-interests-options">
    <%= for interest <- @also_interest_options do %>
      ...

I found the bug while using the picker myself making the discussion thread for the previous post here. Open the panel, check a box, and the panel snaps shut. Open it again, check another box, shut again. Collapsed, it gives no sign anything is selected at all. This was a problem.

I, uh, swallowed a bug? Geez I'm corny.

The bug #

The last panel bug on this blog was a race — three timers and a duplicate event, reproducible twice in many runs. This one is the opposite: perfectly deterministic, wrong every single time, and visible the moment you know where to look.

So reproducible it was (relatively) easy to write a smoke test for it.

A <details> element’s open attribute is written by the browser when the user clicks the summary. The server never hears about it. Meanwhile the composer is a LiveView form with live validation — every keystroke and every checkbox change makes a round trip, the server re-renders, and the patcher re-syncs the DOM to the server’s HTML. The server’s HTML has no open attribute, so the patcher removes it. Typing a single letter in the title field also closed the panel.

The fix #

Give the boolean to the server.

<button type="button" phx-click="toggle_also_interests"
        aria-expanded={to_string(@also_picker_open?)}>
  <%= t("Also show in") %>
  <%= if names != [] do %>
    <span><%= Enum.join(names, ", ") %></span>
  <% end %>
</button>
<div hidden={!@also_picker_open?}>
  ... the checkboxes ...
</div>

The checkbox list is hidden when collapsed, not conditionally rendered. Inputs that leave the DOM leave the form, and a reader who collapses the panel before submitting doesn’t silently lose their picks.

Bug fixed, time for a beer.

Your reply is in the thread. It’ll appear right here in about a minute.Your reply is in the thread. This page will show it after its next build.

Replies come from PopsicleBoat members, which is why there’s no spam. Posting takes you there to sign in (or create an account, it takes a short minute) and confirm your reply, then lands you right back here.

512KB Club Orange Team member