119 lines
3.7 KiB
JavaScript
119 lines
3.7 KiB
JavaScript
(function collonadeClosure() {
|
|
'use strict';
|
|
|
|
/**
|
|
*
|
|
* Async Form Utility
|
|
* prevents form submissions from reloading the page but instead firing an AJAX request
|
|
*
|
|
* Attribute: uw-async-form
|
|
* (works only on <form> elements)
|
|
*
|
|
* Example usage:
|
|
* <form uw-async-form method='POST' action='...'>
|
|
* ...
|
|
*/
|
|
|
|
var ASYNC_FORM_UTIL_NAME = 'asyncForm';
|
|
var ASYNC_FORM_UTIL_SELECTOR = 'form[uw-async-form]';
|
|
|
|
var ASYNC_FORM_INITIALIZED_CLASS = 'check-all--initialized';
|
|
var ASYNC_FORM_RESPONSE_CLASS = 'async-form__response';
|
|
var ASYNC_FORM_LOADING_CLASS = 'async-form--loading';
|
|
var ASYNC_FORM_MIN_DELAY = 600;
|
|
var ASYNC_FORM_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.';
|
|
|
|
var asyncFormUtil = function(element) {
|
|
|
|
var lastRequestTimestamp = 0;
|
|
|
|
function init() {
|
|
if (!element) {
|
|
throw new Error('Async Form Utility cannot be setup without an element!');
|
|
}
|
|
|
|
if (element.classList.contains(ASYNC_FORM_INITIALIZED_CLASS)) {
|
|
return false;
|
|
}
|
|
|
|
element.addEventListener('submit', submitHandler);
|
|
|
|
element.classList.add(ASYNC_FORM_INITIALIZED_CLASS);
|
|
|
|
return {
|
|
name: ASYNC_FORM_UTIL_NAME,
|
|
element: element,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
function processResponse(response) {
|
|
var responseElement = makeResponseElement(response.content, response.status);
|
|
var parentElement = element.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, element);
|
|
element.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();
|
|
|
|
element.classList.add(ASYNC_FORM_LOADING_CLASS)
|
|
lastRequestTimestamp = Date.now();
|
|
|
|
var url = element.getAttribute('action');
|
|
var headers = { };
|
|
var body = new FormData(element);
|
|
|
|
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 = ASYNC_FORM_DEFAULT_FAILURE_MESSAGE;
|
|
if (options.i18n && options.i18n.asyncFormFailure) {
|
|
failureMessage = options.i18n.asyncFormFailure;
|
|
}
|
|
processResponse({ content: failureMessage });
|
|
|
|
element.classList.remove(ASYNC_FORM_LOADING_CLASS);
|
|
});
|
|
}
|
|
|
|
return init();
|
|
};
|
|
|
|
if (UtilRegistry) {
|
|
UtilRegistry.register({
|
|
name: ASYNC_FORM_UTIL_NAME,
|
|
selector: ASYNC_FORM_UTIL_SELECTOR,
|
|
setup: asyncFormUtil
|
|
});
|
|
}
|
|
})();
|