marick
Checkboxes as lists of ids: common case?
Phoenix.HTML.Form has a checkbox function, but it seems targeted at standalone boolean checkboxes, like hiding/showing a password:
However, another common case (I think) is to select from a list of options, like this:
(Because I don’t think many ordinary humans are comfortable using multiple-select <select> tags.)
When I created this form, I wanted the POST to produce a list of chosen_animal_ids. My code was this:
checkbox(f, :animal_ids,
name: "#{input_name(:animals, :chosen_animal_ids)}[]",
value: a.id,
hidden_input: false)
That doesn’t actually work. Unlike other Phoenix.HTML.Form functions, value: here doesn’t set the HTML value attribute. The result of the above is this HTML:
<input type="checkbox" value="true">
(I don’t understand the checkbox documentation for value: “the value used to check if a checkbox is checked or unchecked. The default value is extracted from the form data if available”. So I could be missing something obvious.)
Working code is this:
checkbox(f, :animal_ids,
name: "#{input_name(:animals, :chosen_animal_ids)}[]",
checked_value: a.id,
# ^^^^^^^
hidden_input: false)
Questions:
- Am I doing something completely wrong?
- Are there libraries that extend Phoenix.HTML.Form that I should know about? (I’ve only found this which addresses a different concern.)
- Would it be useful for Phoenix.HTML.Form to have a special function for this case (like the one I’m about to write) - or documentation that describes the issue? (In addition to the
valueconclusion, I think the explicitname: "#{input_name(:animals, :chosen_animal_ids)}[]"is kind of gross.)
Most Liked
kokolegorille
I have build my helper for this case, it is mostly coming from this post
It is checked, not checked_value
Here is one I made for Bootstrap 4
def multiselect_checkboxes(form, field, options, opts \\ []) do
{selected, _} = get_selected_values(form, field, opts)
selected_as_strings = Enum.map(selected, &"#{&1}")
# Use inline mode by default
class = opts[:class] || "form-check form-check-inline"
# By default, input is active (not disabled)
disabled = opts[:disabled]
for {value, key} <- options, into: [] do
id = input_id(form, field, key)
content_tag(:div, class: class) do
[
tag(:input,
name: input_name(form, field) <> "[]",
id: id,
class: "form-check-input",
type: "checkbox",
value: key,
checked: Enum.member?(selected_as_strings, "#{key}"),
disabled: disabled
),
content_tag(:label, value, class: "form-check-label", for: id)
]
end
end
end
defp get_selected_values(form, field, opts) do
{selected, opts} = Keyword.pop(opts, :selected)
param = field_to_string(field)
case form do
%{params: %{^param => sent}} ->
{sent, opts}
_ ->
{selected || input_value(form, field), opts}
end
end
defp field_to_string(field) when is_atom(field), do: Atom.to_string(field)
defp field_to_string(field) when is_binary(field), do: field
and I call it like this
<label for="roles"><%= gettext("Roles") %></label>
<div class="form-group">
<%=
multiselect_checkboxes(
f,
:roles,
select_roles(),
selected: user_selected_roles(@changeset.data),
disabled: is_self_and_last_admin?(
@current_user, @changeset.data
)
)
%>
</div>
Some of the private functions are missing, but there are not difficult to reproduce.
There is nothing specific to Phoenix, I do remember having the same problem with Rails ![]()
marick
Yes, it’s “value” if you use tag, “checked_value” if you use checkbox.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance











