Search code examples
phoenix-live-view

Phoenix Live View keeps rebuilding a DOM element with phx-update="ignore"


In my contrived chat app, I have a timestamp at the bottom that is supposed to tell when the page loaded. Adding chats should not change it, and I included a phx-update="ignore" attribute on the div containing the timestamp to prevent that:

<div id="date" phx-hook="Date" phx-update="ignore"></div>

However, the timestamp does get updated when chats are added. Here is the initial state:

Before adding chat

Then I click New Chat and the dialog appears:

Adding chat

I inspected the DOM and I know that step did not change the timestamp. However, when I press the Save button, the timestamp does change:

After adding chat

How can I prevent that from happening?


Solution

  • The Save button in the dialog was triggering a redirect that caused the page to refresh, so I fixed that by replacing the dialog with some widgets with phx-hook fields, sending the chats to the server with pushEvent in app.js:

    index.html.leex

    <input id="usernameinput" placeholder="Your name" phx-update="ignore"/>
    <input id="chatinput" placeholder="Say something"/>
    <button id="newchatbtn" phx-hook="ChatSend">Send</button>
    

    app.js:

    Hooks.ChatSend = {
        mounted() {
            let viewHook = this
            this.el.addEventListener("click", function() {
                let uni = document.getElementById("usernameinput")
                let ci = document.getElementById("chatinput")
                viewHook.pushEvent("send-chat", {msg: ci.value, username: uni.value})
            })
        }
    }
    

    index.ex:

      @impl true
      def handle_event("send-chat", %{"msg" => msg, "username" => username}, socket) do
        {:ok, c} = Chats.create_chat(%{username: username, body: msg})
        cs = socket.assigns.chats
        cs = cs ++ [c]
        socket = assign(socket, :chats, cs)
        {:noreply, socket}
      end
    

    Here is the commit.