Conditionally render element attribute in lv 0.17.9

Migrating templates from 0.15.x to 0.17.9.

Any ideas on how to conditionally render an element attribute?
Before I could simply do it as shown below, but it doesn’t work anymore:

<div <%= if @foo do %> my-attribute<% end %>>
</div>

Try:

<div my-attribute={@foo}>
</div>

Falsy values (nil, false) will not show my-attribute on the element, true will render my-attribute

2 Likes

Thanks, but are you sure it won’t be rendered if falsy? Asking because I have plenty of templates to migrate and a non trivial amount of JS depending on such attributes.

Also, is this documented anywhere (haven’t found it in the guides)? If not, it should be.

are you sure it won’t be rendered if falsy?

Positive. The new HEEx syntax uses {} to interpolate values over <%= %>

<div data-my-attr={false}></div>

Will render like:

<div></div>

You can also do string interpolation for things like conditionally adding classes:
<div class={"px-4 #{if some_condition, do: "py-4"}"}></div>

If some_condition is true, you’ll get:

<div class="px-4 py-4"></div>

If false/nil, you’ll get:
<div class="px-4 "></div>

2 Likes

Thanks a lot!

You can also do something like this:

<div class={["px-4", some_condition && "py-4" ]}>
6 Likes

Did not know this - Much cleaner!

2 Likes

This is VERY interesting. Can you please point out where this is documented. I wonder if there’s more to it.

To rephrase: does the interpolation behave exactly like string interpolation but with change tracking?

Playing with examples now. Just noticed that the rendered output varies based on the attribute it is being defined for. For example:

<div class={ [ "foo", "bar"]}></div>

renders into

<div class="foo bar"></div>

(with a space character added between the two class names)

While:

<div something-else={ [ "foo", "bar"]}></div>

renders into:

<div something-else= "foobar"></div>

Again, will really appreciate if there are in-depth docs on this. Thanks.

1 Like

Only class has that behavior:

The following attribute values have special meaning:

true - if a value is true, the attribute is rendered with no value at all. For example, <input required={true}> is the same as <input required>;
false or nil - if a value is false or nil, the attribute is not rendered;
list (only for the class attribute) - each element of the list is processed as a different class. nil and false elements are discarded.

Read more here:

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Helpers.html#sigil_H/2-heex-extension-defining-attributes

2 Likes

Thanks!

Don’t understand why they chose to document this under sigil_H function as it applies to templates regardless of how their rendering is invoked (i.e. may as well be implicit), but it’s good to know where it is and that this is all to it.

1 Like