Phx-blur with contenteditable

I was wondering if anyone has tried using the phx-blur with a contenteditable div? I have been fighting with it for a few hours and I can find no way to get the value within the div sent along with the event.

<div phx-blur="update_event" contenteditable="true">
Original Value
</div>
1 Like

We don’t currently track content-editable elements. Since JS is going to be required one way or the other if you want to wire things up with a form, we may never handle this in LV itself. Fortunately JS hooks are there to meet your needs:

  <%= label f, :username %>
  <div contenteditable="true" 
       phx-hook="ContentEditable"
       phx-update="ignore"
       data-name="user[username]">
    <%= @changeset.data.username %>
  </div>
  <%= text_input f, :username, style: "display: none;" %>
  <%= error_tag f, :username %>
let Hooks = {}
Hooks.ContentEditable = {
  mounted(){
    let form = this.el.closest("form")
    let targetInput = form.querySelector(`[name="${this.el.dataset.name}"]`)
    this.el.addEventListener("input", e => {
      // push event to the server
      // this.pushEvent("update_event", {content: this.el.innerText})
      // or copy to hidden input and trigger parent form event
      targetInput.value = this.el.innerText
      targetInput.dispatchEvent(new Event("input", {bubbles: true}))
    })
  }
}

let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks})

liveSocket.connect()
3 Likes

replace addEventListener("input" with addEventListener("focusout" if you want to trigger on blur instead of keypress

1 Like

I hadn’t heard about hooks until this afternoon and hoped they might be answer. Thanks for your help and all the hard work on LiveView/Phoenix.

1 Like