Search code examples
phoenix-live-view

How do I prevent a Phoenix Live View from removing DOM elements put there by JavaScript?


I haven't yet found a way to consistently prevent Phoenix Live Views from removing elements from the DOM that were put there by JavaScript. Here is a snippet from a crude chat app that uses JavaScript to add a smiley face after the page loads:


<span><%= live_patch "New Chat", to: Routes.chat_index_path(@socket, :new) %></span>

<div id="smiley" style="font-size: 80px" phx-update="ignore"></div>

<script>
  $(document).ready(function() {
    $('#smiley').html('😃')
  });
</script>

initial page with smiley face added by JavaScript

The phx-update="ignore" attribute prevents the smiley face from disappearing right away, but adding a new chat causes it to disappear:

page after adding chat, with smiley face removed by Live View


Solution

  • You can prevent it from disappearing after New Chat by using phx-hook like this:

    <div id="smiley" style="font-size: 80px" phx-hook="Smiley"></div>
    

    and in app.js:

    
    let Hooks = {}
    Hooks.Smiley = {
        mounted() {
            this.el.innerHTML = '😃'
        }
    }
    
    let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: Hooks})
    

    The complete code is here: https://github.com/ijt/rantclub/tree/c383530ce9749beb21f2c60605576f0d047043f8.

    One caveat: for some reason this does not prevent Delete from removing the smiley face.