#javascript #ruby-on-rails #ruby #rails-activestorage
#javascript #ruby-on-rails #ruby #rails-activestorage
Вопрос:
Мне удалось получить прямые загрузки, работающие с simple_form gem, используя вспомогательный метод параметров ввода. Проблема, с которой я сталкиваюсь, заключается в том, что запуск прямой загрузки приведет к отображению индикатора выполнения вместо ввода файла, и я не могу повторно загрузить другой файл, если к этому файловому вводу прикреплен неправильный файл. По сути, я пытаюсь заменить файлы, которые могли быть загружены — после факта. Как я могу запретить прямой загрузке заменять ввод файла индикатором выполнения?
direct_upload_file_input.rb
class DirectUploadFileInput < SimpleForm::Inputs::FileInput
def input_html_options
super.merge({direct_upload: true})
end
end
_form.html.erb
has_one :media_file
<%= f.input :media_file, as: :file, input_html: {:onchange => "activate_progress_bar", direct_upload: true}, label: false %>
direct_upload.js
// direct_uploads.js
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"></span>
</div>
`)
target.previousElementSibling.querySelector(`.direct-upload__filename`).textContent = file.name
})
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")
})
Ответ №1:
В вашем direct-upload:initialize
методе вы заменяете target
на индикатор выполнения div. target
В этом случае устанавливается event.target
значение, которое является вашим полем ввода файла. Вам нужно заменить или вставить индикатор выполнения в другой элемент страницы, если вы хотите сохранить ввод файла, но также отображать индикатор выполнения. Что-то вроде…
let progress = document.getElementById('progress');
progress.innerHTML =
`<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"></span>
</div>`