Handle Paste Images in Phoenix Live View Form Uploads

First I followed this video:






But then I wanted to be able to paste an image from the clipboard. Apparently all you have to do is catch the paste event on window and put all the files it gives you into the <input> tag.

I added this into app.js.

Assigning the files to the input

window.addEventListener('paste', e => {
  let files = e.clipboardData.files;
  let input = document.querySelector("input[type=file]")
  if(!files || !input) return; 
  input.files = files; 
});

Going line-by-line through the above code:

  1. Listen for paste events on the window
  2. Any copied images are available as clipboardData.files
  3. Look for a file upload input (this assumes there will only be one on the page)
  4. If we don’t have files and an upload, don’t do anything
  5. Assign the files to the input ### But this wasn’t quite enough.

To get Phoenix LiveView to pick up the change I needed to create an event that would bubble up to window. These lines should be added to the event handler above (after line 5, before line 6).

  var event = document.createEvent("HTMLEvents"); 
  event.initEvent("input", true, true); 
  input.dispatchEvent(event); 
  1. Create a new event
  2. Set the event name to “input” (could also be “change”) and must bubble to the window to trigger an update in Phoenix Live View
  3. Event needs to be dispatched by the input

How did I figure this out?

It took several hours... The most useful thing I did was to change the import in app.js from
import LiveSocket from "phoenix_live_view" to use the uncompiled JS file instead. This meant I could add breakpoints in Chrome to figure out what happened when a change is made and how to create the right kind of event to trigger the Live View hooks.

Anyway hopefully I’ve saved you the trouble!

Find me on Twitter

Get your free book

Sign up for my newsletter to get weekly tips on mood tracking, happiness data analysis and forming better habits.

I will send you a copy of my eBook about mood tracking.

Find out more

*
indicates required