bitcrowd / bitstyles_phoenix

A collection of Elixir phoenix helpers for bitstyles
ISC License
12 stars 0 forks source link

Pass `label_opts[for: ID]` when a custom ID is provided on `ui_input` #126

Open agatheblues opened 5 months ago

agatheblues commented 5 months ago

When passing an ui_input like this:

<.ui_input
    form={f}
    field={:types}
    type={:checkbox}
    name={"#{input_name(f, :types)}[]"}
    value={"awesome"}
    checked_value={"awesome"}
  />

Because of the checked value, the id attribute of the input will be autogenerated by Phoenix to be myform_types_awesome (see https://github.com/phoenixframework/phoenix_html/blob/d6c9d5369096540462d837e231f1a1eb5fb50042/lib/phoenix_html/form.ex#L1176). It suffixes the name with the checked_value.

But the label helper (https://github.com/phoenixframework/phoenix_html/blob/d6c9d5369096540462d837e231f1a1eb5fb50042/lib/phoenix_html/form.ex#L1823) doesn't know about the checked_value and will have for=myform_types or so.

As a result the input id and label's for do not match.

We can alleviate this by passing a custom id to ui_input but then it only works if you pass label_opts=[for: CUSTOM_ID] as well.

I was wondering if ui_input should by default pass the label_opts[for: CUSTOM_ID] automatically if an id was given to the ui_input?

angelikatyborska commented 5 months ago

Sounds like a bug in phoenix. It will produce labels that aren't associated with their inputs, right?

But yes, we should definitely automatically pass along a custom input id to the label in ui_input. I cannot picture a scenario where you would want the label not to be associated with the input.

agatheblues commented 5 months ago

It will produce labels that aren't associated with their inputs, right?

Yes, exactly. I'm not sure if it's a legit bug because that would mean the label needs to know the checked_value and the name of the associated input -> is there a good way to figure out which input is associated?

Alternatively ui_input could also adopt the same behaviour as phoenix when a name and checked_value are given:

if String.ends_with?(opts[:name], "[]"),
          do: input_id(form, field, checked_value),
          else: input_id(form, field)

and pass this id to the label as well 🤔

angelikatyborska commented 5 months ago

Why does even the id of the checkbox need to be different if checked_value was passed? Why is phoenix doing this https://github.com/phoenixframework/phoenix_html/blob/d6c9d5369096540462d837e231f1a1eb5fb50042/lib/phoenix_html/form.ex#L1176 ? 🤔

agatheblues commented 5 months ago

In my case I had a list of checkboxes for one array field. For example types[]=foo&types[]=bar should save types: ["foo", "bar"] on my record. The checked_value of each checkbox is set to foo and bar. If the id is not suffixed with the checked_value, then the inputs will have the same id as they represent the same field. I think that's the reason!

angelikatyborska commented 5 months ago

Alright, then it makes sense. We could do both in ui_input: