marick

marick

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.)

Showing Posts 1 to 4

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 OP

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

kokolegorille

kokolegorille

ah, ok :slight_smile:

marick

marick OP

Actually, working with checkbox is awkward enough that I think you were right to work with tag.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews