fradrive/frontend/src/utils/async-form/async-form.js

96 lines
2.6 KiB
JavaScript

import { Utility } from '../../core/utility';
import './async-form.scss';
const ASYNC_FORM_INITIALIZED_CLASS = 'check-all--initialized';
const ASYNC_FORM_RESPONSE_CLASS = 'async-form__response';
const ASYNC_FORM_LOADING_CLASS = 'async-form--loading';
const ASYNC_FORM_MIN_DELAY = 600;
const MODAL_SELECTOR = '.modal';
const MODAL_HEADER_KEY = 'Is-Modal';
const MODAL_HEADER_VALUE = 'True';
@Utility({
selector: 'form[uw-async-form]',
})
export class AsyncForm {
_lastRequestTimestamp = 0;
_element;
_app;
constructor(element, app) {
if (!element) {
throw new Error('Async Form Utility cannot be setup without an element!');
}
this._element = element;
this._app = app;
if (this._element.classList.contains(ASYNC_FORM_INITIALIZED_CLASS)) {
return false;
}
this._element.addEventListener('submit', this._submitHandler);
this._element.classList.add(ASYNC_FORM_INITIALIZED_CLASS);
}
destroy() {
// TODO
}
_processResponse(response) {
const responseElement = this._makeResponseElement(response.content, response.status);
const parentElement = this._element.parentElement;
// make sure there is a delay between click and response
const delay = Math.max(0, ASYNC_FORM_MIN_DELAY + this._lastRequestTimestamp - Date.now());
setTimeout(() => {
parentElement.insertBefore(responseElement, this._element);
this._element.remove();
}, delay);
}
_makeResponseElement(content, status) {
const responseElement = document.createElement('div');
status = status || 'info';
responseElement.classList.add(ASYNC_FORM_RESPONSE_CLASS);
responseElement.classList.add(ASYNC_FORM_RESPONSE_CLASS + '--' + status);
responseElement.innerHTML = content;
return responseElement;
}
_submitHandler = (event) => {
event.preventDefault();
this._element.classList.add(ASYNC_FORM_LOADING_CLASS);
this._lastRequestTimestamp = Date.now();
const url = this._element.getAttribute('action');
const headers = { };
const body = new FormData(this._element);
const isModal = this._element.closest(MODAL_SELECTOR);
if (isModal) {
headers[MODAL_HEADER_KEY] = MODAL_HEADER_VALUE;
}
this._app.httpClient.post({
url: url,
headers: headers,
body: body,
}).then(
(response) => response.json()
).then(
(response) => this._processResponse(response[0])
).catch(() => {
const failureMessage = this._app.i18n.get('asyncFormFailure');
this._processResponse({ content: failureMessage });
this._element.classList.remove(ASYNC_FORM_LOADING_CLASS);
});
}
}