140 lines
3.8 KiB
JavaScript
140 lines
3.8 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
/**
|
|
*
|
|
* Mass Input Utility
|
|
* allows form shapes to be manipulated asynchronously:
|
|
* will asynchronously submit the containing form and replace the contents
|
|
* of the mass input element with the one from the BE response
|
|
* The utility will only trigger an AJAX request if the mass input element has
|
|
* an active/focused element whilst the form is being submitted.
|
|
*
|
|
* Attribute: uw-mass-input
|
|
*
|
|
* Example usage:
|
|
* <form method="POST" action="...">
|
|
* <input type="text">
|
|
* <div uw-mass-input>
|
|
* <input type="text">
|
|
* <button type="submit">
|
|
*/
|
|
|
|
var MASS_INPUT_UTIL_NAME = 'massInput';
|
|
var MASS_INPUT_UTIL_SELECTOR = '[uw-mass-input]';
|
|
|
|
var MASS_INPUT_INITIALIZED_CLASS = 'mass-input--initialized';
|
|
|
|
var massInputUtil = function(element) {
|
|
var massInputId;
|
|
var massInputFormSubmitHandler;
|
|
var massInputForm;
|
|
|
|
function init() {
|
|
if (!element) {
|
|
throw new Error('Mass Input utility cannot be setup without an element!');
|
|
}
|
|
|
|
massInputId = element.id;
|
|
massInputForm = element.closest('form');
|
|
|
|
if (!massInputForm) {
|
|
throw new Error('Mass Input utility cannot be setup without being wrapped in a <form>!');
|
|
}
|
|
|
|
massInputFormSubmitHandler = makeSubmitHandler();
|
|
massInputForm.addEventListener('submit', massInputFormSubmitHandler);
|
|
|
|
// mark initialized
|
|
element.classList.add(MASS_INPUT_INITIALIZED_CLASS);
|
|
|
|
return {
|
|
name: MASS_INPUT_UTIL_NAME,
|
|
element: element,
|
|
destroy: function() {},
|
|
};
|
|
}
|
|
|
|
function makeSubmitHandler() {
|
|
if (!HttpClient) {
|
|
throw new Error('HttpClient not found!');
|
|
}
|
|
|
|
var method = massInputForm.getAttribute('method') || 'POST';
|
|
var url = massInputForm.getAttribute('action') || window.location.href;
|
|
var enctype = massInputForm.getAttribute('enctype') || 'application/json';
|
|
|
|
var requestFn;
|
|
if (HttpClient[method.toLowerCase()]) {
|
|
requestFn = HttpClient[method.toLowerCase()];
|
|
}
|
|
|
|
return function(event) {
|
|
// check if event occured from either a mass input add/delete button or
|
|
// from inside one of massinput's inputs (i.e. they are focused/active)
|
|
var activeElement = element.querySelector(':focus, :active');
|
|
if (!activeElement) {
|
|
return false;
|
|
}
|
|
|
|
event.preventDefault();
|
|
var requestBody = serializeForm();
|
|
|
|
if (requestFn) {
|
|
requestFn(
|
|
url,
|
|
{
|
|
'Content-Type': enctype,
|
|
'Mass-Input-Shortcircuit': massInputId,
|
|
},
|
|
requestBody,
|
|
).then(function(response) {
|
|
return response.text();
|
|
}).then(function(response) {
|
|
processResponse(response);
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
function processResponse(response) {
|
|
element.innerHTML = response;
|
|
|
|
reset()
|
|
|
|
if (UtilRegistry) {
|
|
UtilRegistry.setupAll(element);
|
|
}
|
|
}
|
|
|
|
function serializeForm() {
|
|
var formData = new FormData(massInputForm);
|
|
var formBody = [];
|
|
|
|
for(var formField of formData) {
|
|
var encodedKey = encodeURIComponent(formField[0]);
|
|
var encodedValue = encodeURIComponent(formField[1]);
|
|
formBody.push(encodedKey + "=" + encodedValue);
|
|
}
|
|
|
|
return formBody.join("&");
|
|
}
|
|
|
|
function reset() {
|
|
element.classList.remove(MASS_INPUT_INITIALIZED_CLASS);
|
|
massInputForm.removeEventListener('submit', massInputFormSubmitHandler)
|
|
}
|
|
|
|
return init();
|
|
};
|
|
|
|
// register mass input util
|
|
if (UtilRegistry) {
|
|
UtilRegistry.register({
|
|
name: MASS_INPUT_UTIL_NAME,
|
|
selector: MASS_INPUT_UTIL_SELECTOR,
|
|
setup: massInputUtil
|
|
});
|
|
}
|
|
})();
|