import { DirectUploadsController } from 'activestorage/src/direct_uploads_controller'; import { findElement } from 'activestorage/src/helpers'; import './progress'; // This is a patched copy of https://github.com/rails/rails/blob/master/activestorage/app/javascript/activestorage/ujs.js // It fixes support for multiple input/button elements on direct upload forms const processingAttribute = 'data-direct-uploads-processing'; let started = false; export function start() { if (!started) { started = true; document.addEventListener('submit', didSubmitForm); document.addEventListener('click', didSubmitFormElement); document.addEventListener('ajax:before', didSubmitRemoteElement); } } export default { start }; function didSubmitForm(event) { handleFormSubmissionEvent(event); } function didSubmitFormElement(event) { const { target } = event; if (isSubmitElement(target)) { handleFormSubmissionEvent(formSubmitEvent(event), target); } } function didSubmitRemoteElement(event) { if (event.target.tagName == 'FORM') { handleFormSubmissionEvent(event); } } function formSubmitEvent(event) { return { target: event.target.form, preventDefault() { event.preventDefault(); } }; } function isSubmitElement({ tagName, type, form }) { if (form && (tagName === 'BUTTON' || tagName === 'INPUT')) { return type === 'submit'; } return false; } function handleFormSubmissionEvent(event, button) { const form = event.target; if (form.hasAttribute(processingAttribute)) { event.preventDefault(); return; } const controller = new DirectUploadsController(form); const { inputs } = controller; if (inputs.length) { event.preventDefault(); form.setAttribute(processingAttribute, ''); inputs.forEach(disable); controller.start(error => { form.removeAttribute(processingAttribute); if (error) { inputs.forEach(enable); } else { submitForm(form, button); } }); } } function submitForm(form, button) { button = button || findElement(form, 'input[type=submit]'); if (button) { const { disabled } = button; button.disabled = false; button.focus(); button.click(); button.disabled = disabled; } else { button = document.createElement('input'); button.type = 'submit'; button.style.display = 'none'; form.appendChild(button); button.click(); form.removeChild(button); } } function disable(input) { input.disabled = true; } function enable(input) { input.disabled = false; }