marick

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:

  1. Am I doing something completely wrong?
  2. Are there libraries that extend Phoenix.HTML.Form that I should know about? (I’ve only found this which addresses a different concern.)
  3. 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 value conclusion, I think the explicit name: "#{input_name(:animals, :chosen_animal_ids)}[]" is kind of gross.)

Most Liked

kokolegorille

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 :slight_smile:

marick

marick

Yes, it’s “value” if you use tag, “checked_value” if you use checkbox.

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement