What is the proper way to interpolate boolean attributes like checked
in an input in the new HEEx engine?
For example, in LEEx if I wanted to include it based on some condition, I would do this:
<input type="checkbox" name="web_pages[]" value="<%= w.id %>" <%= if w.id in @selected, do: "checked" %> />
Which would generate HTML like this:
<input type="checkbox" name="web_pages[]" value="1" />
<input type="checkbox" name="web_pages[]" value="2" checked />
Now in HEEx I do this
<input type="checkbox" name="web_pages[]" value={w.id} checked={if w.id in @selected, do: "true", else: nil} />
Which also works, if a nil
value is passed then the checked
attribute won’t be passed at all, but if I pass true
then it will generate this:
<input type="checkbox" name="web_pages[]" value="2" checked="true" />
Which is correct, but longer and a bit uglier. I would have expected that this would work:
<input type="checkbox" name="web_pages[]" value={w.id} {if w.id in @selected, do: "checked"} />
But it doesn’t, it fails with protocol Enumerable not implemented for nil of type Atom
. It looks like interpolation must always be bound to an attribute name in the HTML tag, right?
1 Like
Qqwy
September 28, 2021, 12:19pm
2
It is OK to assign to multiple dynamic attributes at once, using the syntax of your last example.
However, the result is expected to be a keyword-list or a map. Currently you are returning a single string.
Instead, you can do, for instance:
<input type="checkbox" name="web_pages[]" value={w.id} {if w.id in @selected, do: %{checked: true}} />
However, in neither case will the result be a valueless attribute.
I don’t think this is a bad thing. Instead, not supporting this special case makes it easier for the HEEx parser to always generate correct HTML.
<input type="checkbox" checked={@boolean}>
should just work.
3 Likes
Makes sense, I would prefer to be able to generate valueless attributes like checked
instead of checked=true
but it’s not that important, just checking if there was a way to do that.
Thanks!
I’ve no heex project at hand to check, but I’m quite confident it just generates a valueless attribute or no attribute.
1 Like
Ah! It does! The following works as expected, generating a valueless attribute for true
or no attribute for false
.
<input type="checkbox" name="web_pages[]" value={w.id} checked={w.id in @selected} />
Awesome, thanks!
2 Likes
Here is a Surface
reference on boolean attributes
. Is there corresponding documentation in Phoenix Liveview on this subject that we can reference?
Surface (surface-ui.org)