Creating dynamic checkboxes and radio buttons in Phoenix

Published by Johan Tell

In most projects on the web there will be some occurrences of the <input type="radio"> or <input type="checkbox"> control for forms.

While developing forms that require a dynamic set of radio buttons or checkboxes I’ve found that it’s not very well documented on how to get them to work together with labels in Phoenix.

There are multiple ways to accomplish it so I’ll show you my two preferred ways.

Making use of input_id/3

Phoenix.HTML has a nifty little function used internally by the builder methods of radio buttons or check boxes to create the id attributes. However as of this writing it hasn’t been implemented into the builder for labels because there has been no idea on how to do this without working with temporary options. See this pull request for more info.

Notice that the last value passed to input_id must be an atom or a string.

<% medals = [:gold, :silver, :bronze] %>
<% default_medal = :bronze %>

<%= form_for @changeset, medal_path(@conn, :create), fn f -> %>
  <%= label f, :medal, "Choose your medal" %>

  <%= for medal <- medals do %>
    <%= label f, :medal, medal, for: input_id(f, :medal, medal) %>
    <%= radio_button f, :medal, medal, checked: medal == default_medal %>
  <% end %>
<% end %>

Wrapping the radio button in a label

Something many people seem to miss is that labels don’t need a for attribute at all. By putting the target input inside the label it’ll automatically get focused upon clicking the label. Since e3f14d8 Phoenix.HTML supports label/1 which simply takes a block, making it possible to do it like this:

<% medals = [:gold, :silver, :bronze] %>
<% default_medal = :bronze %>

<%= form_for @changeset, medal_path(@conn, :create), fn f -> %>
  <%= label f, :medal, "Choose your medal" %>

  <%= for medal <- medals do %>
    <%= label do %>
      <%= radio_button f, :medal, medal, checked: medal == default_medal %>
      <%= medal %>
    <% end %>
  <% end %>
<% end %>

I hope this can help!

Johan Tell