Apologies for resurrecting an old thread, I’m just trying to use Trix + Phoenix LiveView myself. Did you get to a working solution with upload()
?
I’ve got as far as this:
Custom input
component that has the phx-hook="Trix"
and contains a hidden live_file_input
component to capture files
def input(%{type: "trix"} = assigns) do
~H"""
<div phx-feedback-for={@name} phx-hook="Trix" phx-debounce="blur" id={"#{@id}-container"}>
<.label for={@id}><%= @label %></.label>
<input
type="hidden"
name={@name}
id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
{@rest}
/>
<.live_file_input upload={@upload} class="hidden" />
<div id="trix-editor-container" phx-update="ignore">
<trix-editor class="trix-editor" input={@id}></trix-editor>
</div>
<.error :for={msg <- @errors}><%= msg %></.error>
</div>
"""
end
In JS, callback for uploading files (omitted some of Trix event listeners:
uploadFileAttachment(attachment) {
const { file } = attachment;
const input = document.querySelector("input[name='attachment']");
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
input.files = dataTransfer.files;
// Trigger the LiveView file upload
const upload = this.upload("attachment", [file]);
attachment.setAttributes({ url: "https://via.placeholder.com/150" });
},
This correctly sends data to the component and I get it all here:
def mount(socket) do
{:ok,
socket
|> assign(:uploaded_files, [])
|> allow_upload(:attachment,
accept: ~w(.jpg .jpeg .png),
progress: &handle_progress/3,
max_entries: 10000,
auto_upload: true
)}
end
defp handle_progress(:attachment, entry, socket) do
if entry.done? do
uploaded_file =
consume_uploaded_entry(socket, entry, fn %{path: path} = meta ->
dest = Path.join("priv/static/uploads", Path.basename(path))
File.cp!(path, dest)
# Todo: figure out public URL
{:ok, dest}
end)
socket = assign(socket, uploaded_files: [uploaded_file | socket.assigns.uploaded_files])
{:noreply, put_flash(socket, :info, "file uploaded")}
else
{:noreply, socket}
end
end
Ignoring the fact that dest
isn’t an actual URL to the file, even if I generate one, I don’t think I can pass it back to the JS – attachment.setAttributes({ url: "https://via.placeholder.com/150" });
expects a “saved” URL that’s permanent.
I’m now leaning towards a standalone controller to handle uploads as described in here How to handle file upload using Trix editor in a Phoenix application but I wondered if I’m missing something.