Hey all!
Hope you are doing well ![]()
We are using the new phx 1.7 core components, and the attributes handling of the checkbox one is disturbing to me.
The source code of the entire <.input type="checkbox"> component is available here.
The thing that bothering me the most, is the mixing of the checked and the value attribute:
def input(%{type: "checkbox", value: value} = assigns) do
assigns =
assign_new(assigns, :checked, fn -> Phoenix.HTML.Form.normalize_value("checkbox", value) end)
In raw html, the value attribute is expected to be a string, and to be the value sent when the form is submitted. It can be any string.
But here, it is expected to be a boolean string ie. "true" to act as checked. Any other string, and the checked is false (that’s the point of Phoenix.HTML.Form.normalize_value/2). The checked= attribute, is still expected to be a boolean.
Furthermore, the value="" attributes are hard coded in the component as boolean strings:
<input type="hidden" name={@name} value="false" />
<input
[…]
value="true"
checked={@checked}
/>
So first of all, I find the value attribute very disturbing, since it’s not at all the same logic as the raw html. Note that I understand that we can drift from the raw html specs, but the vast majority of the core components are really close from the html specs.
Then, the value= is in fact pretty useless, since it’s used only as a default for checked=. But, by having it in the def pattern matching, it is de facto required even if unused by the component itself, or face the runtime error (cannot be catch at compile time I reckon sinc the attr macro is used for all the variations of def input).
I understand that having the value attr set as a boolean string is probably handy for reloading the form after submission though, and it may be the root reason for this design, I don’t know.
To sum up:
-
The behavior of
<.input type="checkbox">is in fact really different from native html, I find it misleading:- Type mismatch of the value attribute (bool string vs any string)
- Different usage (checked vs checkbox actual value when checked)
- Can’t set an other actual value than a boolean
-
The implementation is quite frustratring since it forces me to use an attr I don’t want.
-
<input type="checkbox checked={true} />raises for no functional reason
-
I’m not sure how things could be better…
For the first point, maybe renaming the input type in <input type="boolean" /> could be less misleading, and keeping the type="checkbox" acting closer than the html specs? At least, it would assume creating a component that is not from the html specs.
For the second point, something like this would allow at least to not de facto require the value= attribute:
def input(%{type: "checkbox"} = assigns) do
assigns =
assign_new(assigns, :checked, fn -> Phoenix.HTML.Form.normalize_value("checkbox", assigns[:value] || false) end)
I don’t know if I am missing something?




















