Rails Activestorage + DirectUpload javascript progress bar not showing when using "remote:true"
Asked Answered
M

1

25

I have been using Rails ActiveStorage DirectUpload in my Rails app. And here is the code of the form:

<h3>Select Files To Upload</h3>

<%= form_for @uploader, url: uploaders_file_path(@uploader), :html => {:multipart => true} do |f| %>
  <%= f.file_field :file, direct_upload: true,  class: "form-control" %>

  <%= f.button type: "submit", id: "submit-uploader", class: "btn btn-primary btn-md", data: {disable_with: "Uploading..."} do %>
    Upload
  <% end %>
<% end %>

Everything works alright and the progress bar is also showing when i upload the file:

enter image description here

But, when I try to make the form to be submitted as js, the progress bar is not showing even though the file upload is successful. I just added "remote: true" to make the form to be submitted as js. But now the progress bar is no longer showing.

Here is the new code of the form:

<%= form_for @uploader, url: uploaders_file_path(@uploader), remote: true, :html => {:multipart => true} do |f| %>
  <%= f.file_field :file, direct_upload: true,  class: "form-control" %>

  <%= f.button type: "submit", id: "submit-uploader", class: "btn btn-primary btn-md", data: {disable_with: "Uploading..."} do %>
    Upload
  <% end %>
<% end %>

And here is direct_uploads.js code:

addEventListener("direct-upload:initialize", event => {
  const { target, detail } = event
  const { id, file } = detail
  target.insertAdjacentHTML("beforebegin", `
    <div id="direct-upload-${id}" class="direct-upload direct-upload--pending">
      <div id="direct-upload-progress-${id}" class="direct-upload__progress" style="width: 0%"></div>
      <span class="direct-upload__filename">${file.name}</span>
    </div>
  `)
})

addEventListener("direct-upload:start", event => {
  const { id } = event.detail
  const element = document.getElementById(`direct-upload-${id}`)
  element.classList.remove("direct-upload--pending")
})

addEventListener("direct-upload:progress", event => {
  const { id, progress } = event.detail
  const progressElement = document.getElementById(`direct-upload-progress-${id}`)
  progressElement.style.width = `${progress}%`
})

addEventListener("direct-upload:error", event => {
  event.preventDefault()
  const { id, error } = event.detail
  const element = document.getElementById(`direct-upload-${id}`)
  element.classList.add("direct-upload--error")
  element.setAttribute("title", error)
})

addEventListener("direct-upload:end", event => {
  const { id } = event.detail
  const element = document.getElementById(`direct-upload-${id}`)
  element.classList.add("direct-upload--complete")
})

The above code is taken from: https://guides.rubyonrails.org/active_storage_overview.html#direct-uploads

Malacca answered 30/9, 2018 at 23:59 Comment(2)
Also manually submitting the form with js like $(file_field_id).closest('form').submit(); does not show the progress bar.Stalkinghorse
I couldn't reproduce this behavior on a simple rails 5.2.1 app. You can check here for a simple example with a form exactly equal of yours. As long as you have a submit input the progress bar should appear.Stalkinghorse
S
0

Try this DirectUpload guide section.

Working with the DirectUpload class directly let you submit with remote: true.

  1. Catch the submit (event.preventDefault())
  2. Upload file using DirectUpload class. Which provides events to show progress bar and all stuff.
  3. Submit your form by js.

Means more code but its an option.

Sirup answered 21/6, 2020 at 4:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.