class UploadForm { static autoInit() { const nopaqueSubmitForms = document.querySelectorAll('.nopaque-upload-form'); let nopaqueSubmitForm; for (nopaqueSubmitForm of nopaqueSubmitForms) { new UploadForm(nopaqueSubmitForm); } } constructor(formElement) { this.formElement = formElement; this.request = new XMLHttpRequest(); this.formElement.addEventListener('submit', (event) => { event.preventDefault(); this.submit(); }); } submit() { const selectElements = this.formElement.querySelectorAll('select'); let abortElement; let helperTextElement; let helperTextElements; let inputFieldElement; let modal; let modalElement; let progressElement; let selectElement; let tmp; // Check if select elements are filled out properly for (selectElement of selectElements) { if (selectElement.value === '') { inputFieldElement = selectElement.closest('.input-field'); inputFieldElement.querySelector('.select-dropdown').classList.add('invalid'); helperTextElements = inputFieldElement.querySelectorAll('.helper-text'); for (helperTextElement of helperTextElements) { helperTextElement.remove(); } inputFieldElement.insertAdjacentHTML( 'beforeend', 'Please select an option.' ); return; } } // Setup modal tmp = document.createElement('div'); tmp.innerHTML = ` `.trim(); modalElement = document.querySelector('#modals').appendChild(tmp.firstChild); modal = M.Modal.init( modalElement, { dismissible: false, onCloseEnd: () => { modal.destroy(); modalElement.remove(); } } ); modal.open(); // Setup abort handling abortElement = modalElement.querySelector('.abort'); abortElement.addEventListener('click', event => {this.request.abort();}); this.request.addEventListener('abort', event => { this.request.abort(); modal.close(); }); // Setup load handling (after the request completed) this.request.addEventListener('load', event => { const response = JSON.parse(this.request.responseText); let inputError; let inputErrors; let inputFieldElement; let inputName; if (this.request.status === 201) { window.location.href = response.redirect_url; } if (this.request.status === 400) { for ([inputName, inputErrors] of Object.entries(response)) { inputFieldElement = this.formElement.querySelector(`input[name="${inputName}"], select[name="${inputName}"]`).closest('.input-field'); for (inputError of inputErrors) { inputFieldElement.insertAdjacentHTML( 'beforeend', `${inputError}` ); } } } if (this.request.status === 500) { location.reload(); } modal.close(); }); // Setup progress handling progressElement = modalElement.querySelector('.progress > .determinate'); this.request.upload.addEventListener('progress', event => { const progress = Math.floor(100 * event.loaded / event.total); progressElement.style.width = `${progress}%`; }); this.request.open('POST', window.location.href); this.request.send(new FormData(this.formElement)); } }