Phx-click doesn't work on elements that have "display: none;" on them

I’m creating a list of notifications. These are done via bootstrap’s popover element. I create my list, with a "display: none;"

<div style="display:none;" class="notification_list">
  <ul>
    <%= for {n, index} <- Enum.with_index(@notifications) do %>
      <li data-alert_id="<%= index %>" class="alert_li">
        <a href="#" class="alert_message">
          <%= n.type %>
        </a>
        <br />
        <a href="#" phx-hook="notifications" phx-click="notif-read">read</a>
        <div class="clearfix"></div>
      </li>
    <% end %>
  </ul>
</div>

Then I display it with this JS:

$("#notifications").popover({
    title: 'Notifications <a href="#" phx-click="read_all_notifications">Mark all read</a>',
    html: true,
    placement: 'right',
    content: $(".notification_list").html()
  });

There’s a <a id="notifications"> tag where the user clicks.

All of this is working, except for the phx-click part. If I set the lists display to block, the click works fine. However I only want the list to be displayed once the user clicks the icon, however if I hide the list with display: none;, liveview doesn’t correctly setup phx-click listeners. Is there a way to fix this?

2 Likes

The <a>...</a> bit needs to be in the static html rendered from the server, otherwise Live View is not able to track it.

Just add it to the div notification_list.

1 Like

I’m less worried about that one, it’s the ones in the list that are also not working. These are rendered on the page, just hidden

<a href="#" phx-hook="notifications" phx-click="notif-read">read</a>
        <div class="clearfix"></div>

I think something else is going on here, because I am working on a project where LiveView drives a tabbed interface and all tabs other than the current tab are display: none.

I am absolutely by no means an expert here (learning every day), but I don’t understand the placement of the extra double-quote in this line:

<a href="#" phx-hook="notifications" phx-click="notif-read"">read</a>

Sorry, that’s just a typo of where I copied it over from my editor(i removed some other html attrs that were there but not relevant to this, and I left an extra quotation in there, but there’s no double double quote in my actual markup, so it’s not related to that). Fixed.

1 Like

Ah, it could be the way I’m initializing it with bootstrap. When I do this:

$("#notifications").popover({
    title: 'Notifications <a href="#" phx-click="read_all_notifications">Mark all read</a>',
    html: true,
    placement: 'right',
    content: $(".notification_list").html()
  });

It might copy the HTML into a new element then add that to the page. So if phx-click is relying it to be the same element as when the page renders, that could be an issue. Is there a way to reinitialize phx-click listeners at runtime?

That’s probably the reason, yes. I think that that will trigger after the LiveView JS-runtime has inserted the click listeners.

I unfortunately do not know of a way to re-initialize them at runtime.
Maybe it is worth it to manage the modal from within LiveView (or, if necessary, a LiveView JS-hook) instead?