From 3a30aea5df3df93b0a76751870eb8077a16d6cf1 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Sun, 24 Feb 2019 23:00:21 +0100 Subject: [PATCH] =?UTF-8?q?added=20new=20utils=20=C2=BBhttpClient=C2=AB=20?= =?UTF-8?q?and=20=C2=BBasyncForm=C2=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Foundation.hs | 2 ++ static/js/utils/asyncForm.js | 36 +++++++++++++++++++++++++++ static/js/utils/asyncTable.js | 16 ++++++------ static/js/utils/httpClient.js | 32 ++++++++++++++++++++++++ static/js/utils/modal.js | 47 ++++++++++++----------------------- static/js/utils/setup.js | 14 +++++++---- 6 files changed, 104 insertions(+), 43 deletions(-) create mode 100644 static/js/utils/asyncForm.js create mode 100644 static/js/utils/httpClient.js diff --git a/src/Foundation.hs b/src/Foundation.hs index f35c841e7..e3c89b3aa 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1019,8 +1019,10 @@ siteLayout' headingOverride widget = do -- JavaScript utils addScript $ StaticR js_utils_alerts_js addScript $ StaticR js_utils_asidenav_js + addScript $ StaticR js_utils_asyncForm_js addScript $ StaticR js_utils_asyncTable_js addScript $ StaticR js_utils_checkAll_js + addScript $ StaticR js_utils_httpClient_js addScript $ StaticR js_utils_form_js addScript $ StaticR js_utils_inputs_js addScript $ StaticR js_utils_modal_js diff --git a/static/js/utils/asyncForm.js b/static/js/utils/asyncForm.js new file mode 100644 index 000000000..a7086bdc3 --- /dev/null +++ b/static/js/utils/asyncForm.js @@ -0,0 +1,36 @@ +(function collonadeClosure() { + 'use strict'; + + window.utils = window.utils || {}; + + window.utils.asyncForm = function(formElement, options) { + + function setup() { + formElement.addEventListener('submit', function(event) { + event.preventDefault(); + + 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) { + return response.json(); + }).then(function(response) { + console.log('asyncForm: got response', response); + // TODO: process json response once backend returns json + }).catch(function(error) { + console.error('could not fetch or process response from ' + url, { error }); + }); + }); + } + + setup(); + }; +})(); diff --git a/static/js/utils/asyncTable.js b/static/js/utils/asyncTable.js index bc9215374..a7f46a134 100644 --- a/static/js/utils/asyncTable.js +++ b/static/js/utils/asyncTable.js @@ -139,14 +139,16 @@ // fetches new sorted table from url with params and replaces contents of current table function updateTableFrom(url, tableOptions) { + if (!window.utils.httpClient) { + throw new Error('httpClient not found!'); + } + tableOptions = tableOptions || {}; - fetch(url, { - credentials: 'same-origin', - headers: { - 'Accept': 'text/html', - [shortCircuitHeader]: tableIdent - } - }).then(function(response) { + var headers = { + 'Accept': 'text/html', + [shortCircuitHeader]: tableIdent + }; + window.utils.httpClient.get(url, headers).then(function(response) { if (!response.ok) { throw new Error('Looks like there was a problem fetching ' + url.href + '. Status Code: ' + response.status); } diff --git a/static/js/utils/httpClient.js b/static/js/utils/httpClient.js new file mode 100644 index 000000000..18d82fbb2 --- /dev/null +++ b/static/js/utils/httpClient.js @@ -0,0 +1,32 @@ +(function collonadeClosure() { + 'use strict'; + + window.utils = window.utils || {}; + + window.utils.httpClient = (function() { + + function _fetch(url, method, additionalHeaders, body) { + var requestOptions = { + credentials: 'same-origin', + headers: { }, + method: method, + body: body, + }; + + Object.keys(additionalHeaders).forEach(function(headerKey) { + requestOptions.headers[headerKey] = additionalHeaders[headerKey]; + }); + + return fetch(url, requestOptions); + } + + return { + get: function(url, headers) { + return _fetch(url, 'GET', headers); + }, + post: function(url, headers, body) { + return _fetch(url, 'POST', headers, body); + }, + } + })(); +})(); diff --git a/static/js/utils/modal.js b/static/js/utils/modal.js index 6d12da8d5..71a48be4f 100644 --- a/static/js/utils/modal.js +++ b/static/js/utils/modal.js @@ -10,25 +10,14 @@ var MAIN_CONTENT_CLASS = 'main__content-body' var MODAL_CLOSABLE_FLAG = 'closeable'; var MODAL_DYNAMIC_FLAG = 'dynamic'; + var MODAL_HEADERS = { + 'Is-Modal': 'True', + }; var OVERLAY_CLASS = 'modal__overlay'; var OVERLAY_OPEN_CLASS = 'modal__overlay--open'; var CLOSER_CLASS = 'modal__closer'; var AJAX_SUBMIT_FLAG = 'ajaxSubmit'; - // helper function for convenient http requests with appropriate headers - function httpRequest(url, method, body) { - var requestOptions = { - method: method, - credentials: 'same-origin', - headers: { - 'Is-Modal': 'True', - }, - body: body, - }; - - return fetch(url, requestOptions); - } - window.utils.modal = function(modalElement, options) { if (!modalElement || modalElement.classList.contains(JS_INITIALIZED_CLASS)) { @@ -73,21 +62,12 @@ function setupForm() { var form = modalElement.querySelector('form'); - if (form && AJAX_SUBMIT_FLAG in form.dataset) { - form.addEventListener('submit', function(event) { - event.preventDefault(); + if (form) { + window.utils.setup('form', form); - var url = form.getAttribute('action'); - var body = new FormData(form); - - return httpRequest(url, form.method, body).then(function(response) { - return response.json(); - }).then(function(response) { - // TODO: process json response once backend returns json - }).catch(function(error) { - console.error('could not fetch or process response from ' + url, { error }); - }); - }); + if (AJAX_SUBMIT_FLAG in form.dataset) { + window.utils.setup('asyncForm', form, { headers: MODAL_HEADERS }); + } } } @@ -101,9 +81,14 @@ } function fillModal(url) { - httpRequest(url, 'GET').then(function(response) { - response.text().then(processResponse); - }); + if (!window.utils.httpClient) { + throw new Error('httpClient not found! Can\' fetch modal content from ' + url); + } + + window.utils.httpClient.get(url, MODAL_HEADERS) + .then(function(response) { + response.text().then(processResponse); + }); } function processResponse(reponseBody) { diff --git a/static/js/utils/setup.js b/static/js/utils/setup.js index 36e61a9b7..7068bc476 100644 --- a/static/js/utils/setup.js +++ b/static/js/utils/setup.js @@ -47,11 +47,15 @@ document.addEventListener('setup', listener); - document.dispatchEvent(new CustomEvent('setup', { - detail: { targetUtil: utilName, module: 'none' }, - bubbles: true, - cancelable: true, - })); + // put a slight delay on the setup event in order to allow for all dependencies to load + window.setTimeout(function() { + document.dispatchEvent(new CustomEvent('setup', { + detail: { targetUtil: utilName, module: 'none' }, + bubbles: true, + cancelable: true, + })); + }, 10); + }; window.utils.teardown = function(utilName) {