96 lines
2.6 KiB
JavaScript
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);
|
|
});
|
|
}
|
|
}
|