From 11c5cd36534729c2d03d975be6c7d06a001f3208 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Tue, 23 Apr 2019 13:40:03 +0200 Subject: [PATCH] add massInput js util --- src/Foundation.hs | 1 + static/js/utils/massInput.js | 127 +++++++++++++++++++ templates/widgets/massinput/massinput.hamlet | 2 +- 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 static/js/utils/massInput.js diff --git a/src/Foundation.hs b/src/Foundation.hs index 46e176a19..a05a45558 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1175,6 +1175,7 @@ siteLayout' headingOverride widget = do addScript $ StaticR js_utils_checkAll_js addScript $ StaticR js_utils_form_js addScript $ StaticR js_utils_inputs_js + addScript $ StaticR js_utils_massInput_js addScript $ StaticR js_utils_modal_js addScript $ StaticR js_utils_showHide_js -- addScript $ StaticR js_utils_tabber_js diff --git a/static/js/utils/massInput.js b/static/js/utils/massInput.js new file mode 100644 index 000000000..7b58bb625 --- /dev/null +++ b/static/js/utils/massInput.js @@ -0,0 +1,127 @@ +(function() { + 'use strict'; + + /** + * + * Mass Input Utility + * allows form shapes to be manipulated asynchronously: + * will asynchronously submit the form and replace the contents of the + * mass input with the one from the BE response + * + * Attribute: uw-mass-input + * (will be set up automatically on tables) + * + * Example usage: + * (table with one column thats only checkboxes) + */ + + 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
!'); + } + + massInputFormSubmitHandler = makeSubmitHandler(massInputForm); + 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(massInputForm) { + 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) { + event.preventDefault(); + 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); + } + var requestBody = formBody.join("&"); + + if (requestFn) { + requestFn( + url, + { + 'Content-Type': enctype, + 'Mass-Input-Shortcircuit': massInputId, + 'Upgrade-Insecure-Requests': 1, + }, + requestBody, + ).then(function(response) { + return response.text() + }).then(function(response) { + processResponse(response); + }); + } + }; + } + + function processResponse(response) { + var responseElement = document.createElement('div'); + responseElement.innerHTML = response; + var newWrapperContents = responseElement.querySelector('#' + massInputId); + element.innerHTML = newWrapperContents.innerHTML; + + reset() + + if (UtilRegistry) { + UtilRegistry.setupAll(element); + } + } + + 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 + }); + } +})(); diff --git a/templates/widgets/massinput/massinput.hamlet b/templates/widgets/massinput/massinput.hamlet index 3dde7384d..9a8ef2534 100644 --- a/templates/widgets/massinput/massinput.hamlet +++ b/templates/widgets/massinput/massinput.hamlet @@ -1,5 +1,5 @@ $newline never -
+
#{csrf} ^{shapeInput} ^{miWidget}