106 lines
2.5 KiB
JavaScript
106 lines
2.5 KiB
JavaScript
|
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;
|
||
|
}
|