fradrive/static/js/utils/asyncForm.js
2019-03-10 16:15:34 +01:00

87 lines
2.8 KiB
JavaScript

(function collonadeClosure() {
'use strict';
window.utils = window.utils || {};
var ASYNC_FORM_RESPONSE_CLASS = 'async-form-response';
var ASYNC_FORM_LOADING_CLASS = 'async-form-loading';
var ASYNC_FORM_MIN_DELAY = 600;
var DEFAULT_FAILURE_MESSAGE = 'The response we received from the server did not match what we expected. Please let us know this happened via the help widget in the top navigation.';
window.utils.asyncForm = function(formElement, options) {
options = options || {};
var lastRequestTimestamp = 0;
function setup() {
formElement.addEventListener('submit', submitHandler);
}
function processResponse(response) {
var responseElement = makeResponseElement(response.content, response.status);
var parentElement = formElement.parentElement;
// make sure there is a delay between click and response
var delay = Math.max(0, ASYNC_FORM_MIN_DELAY + lastRequestTimestamp - Date.now());
setTimeout(function() {
parentElement.insertBefore(responseElement, formElement);
formElement.remove();
}, delay);
}
function makeResponseElement(content, status) {
var 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;
}
function submitHandler(event) {
event.preventDefault();
formElement.classList.add(ASYNC_FORM_LOADING_CLASS)
lastRequestTimestamp = Date.now();
var url = formElement.getAttribute('action');
var headers = { };
var body = new FormData(formElement);
if (options && options.headers) {
Object.keys(options.headers).forEach(function(headerKey) {
headers[headerKey] = options.headers[headerKey];
});
}
window.utils.httpClient.post(url, headers, body)
.then(function(response) {
if (response.headers.get("content-type").indexOf("application/json") !== -1) {// checking response header
return response.json();
} else {
throw new TypeError('Unexpected Content-Type. Expected Content-Type: "application/json". Requested URL:' + url + '"');
}
}).then(function(response) {
processResponse(response[0]);
}).catch(function(error) {
var failureMessage = DEFAULT_FAILURE_MESSAGE;
if (options.i18n && options.i18n.asyncFormFailure) {
failureMessage = options.i18n.asyncFormFailure;
}
processResponse({ content: failureMessage });
formElement.classList.remove(ASYNC_FORM_LOADING_CLASS);
});
}
setup();
return {
scope: formElement,
destroy: function() {},
};
};
})();