add htmlhelpers (fns from httpclient)

This commit is contained in:
Felix Hamann 2019-05-15 23:16:27 +02:00
parent d95edd662e
commit cc3f3fe41a
7 changed files with 100 additions and 63 deletions

View File

@ -1340,6 +1340,7 @@ siteLayout' headingOverride widget = do
addScript $ StaticR js_polyfills_urlPolyfill_js addScript $ StaticR js_polyfills_urlPolyfill_js
-- JavaScript services -- JavaScript services
addScript $ StaticR js_services_utilRegistry_js addScript $ StaticR js_services_utilRegistry_js
addScript $ StaticR js_services_htmlHelpers_js
addScript $ StaticR js_services_httpClient_js addScript $ StaticR js_services_httpClient_js
addScript $ StaticR js_services_i18n_js addScript $ StaticR js_services_i18n_js
-- JavaScript utils -- JavaScript utils

View File

@ -0,0 +1,33 @@
(function () {
'use strict';
window.HtmlHelpers = (function() {
function _prefixIds(element) {
var idPrefix = Math.floor(Math.random() * 100000);
var idAttrs = ['id', 'for', 'data-conditional-input', 'data-modal-trigger'];
idAttrs.forEach(function(attr) {
Array.from(element.querySelectorAll('[' + attr + ']')).forEach(function(input) {
var value = idPrefix + '__' + input.getAttribute(attr);
input.setAttribute(attr, value);
});
});
}
function parseResponse(response) {
return response.text().then(function (responseText) {
var docFrag = document.createRange().createContextualFragment(responseText);
_prefixIds(docFrag);
return Promise.resolve(docFrag);
},
function (error) {
return Promise.reject(error);
}).catch(function (error) { console.error(error); });
}
return {
parseResponse: parseResponse,
}
})();
})();

View File

@ -25,7 +25,9 @@
return fetch(options.url, requestOptions).then( return fetch(options.url, requestOptions).then(
function(response) { function(response) {
_responseInterceptors.forEach(function(interceptor) { interceptor(response); }); _responseInterceptors.forEach(function(interceptor) {
interceptor(response, options);
});
return Promise.resolve(response); return Promise.resolve(response);
}, },
function(error) { function(error) {
@ -36,34 +38,6 @@
}); });
} }
function parseHTML(response, idPrefix) {
if (!idPrefix) {
idPrefix = Math.floor(Math.random() * 100000);
}
var contentType = response.headers.get("content-type");
if (contentType.indexOf("text/html") === -1) {
throw new Error('Server returned ' + contentType + ' when HTML was expected');
}
return response.text().then(function (responseText) {
var docFrag = document.createRange().createContextualFragment(responseText);
var idAttrs = ['id', 'for', 'data-conditional-input', 'data-modal-trigger'];
idAttrs.forEach(function(attr) {
Array.from(docFrag.querySelectorAll('[' + attr + ']')).forEach(function(input) {
var value = idPrefix + '__' + input.getAttribute(attr);
input.setAttribute(attr, value);
});
});
return Promise.resolve(docFrag);
},
function (error) {
return Promise.reject(error);
}).catch(function (error) { console.error(error); });
}
return { return {
get: function(args) { get: function(args) {
args.method = 'GET'; args.method = 'GET';
@ -74,7 +48,25 @@
return _fetch(args); return _fetch(args);
}, },
addResponseInterceptor: addResponseInterceptor, addResponseInterceptor: addResponseInterceptor,
parseHTML: parseHTML, ACCEPT: {
TEXT_HTML: 'text/html',
JSON: 'application/json',
},
} }
})(); })();
// HttpClient ships with its own little interceptor to throw an error
// if the response does not match the expected content-type
function contentTypeInterceptor(response, options) {
if (!options || !options.accept) {
return;
}
var contentType = response.headers.get("content-type");
if (!contentType.match(options.accept)) {
throw new Error('Server returned with "' + contentType + '" when "' + options.accept + '" was expected');
}
}
HttpClient.addResponseInterceptor(contentTypeInterceptor);
})(); })();

View File

@ -96,21 +96,21 @@
headers[MODAL_HEADER_KEY] = MODAL_HEADER_VALUE; headers[MODAL_HEADER_KEY] = MODAL_HEADER_VALUE;
} }
HttpClient.post({ url: url, headers: headers, body: body }) HttpClient.post({
.then(function(response) { url: url,
if (response.headers.get("content-type").indexOf("application/json") !== -1) {// checking response header headers: headers,
return response.json(); body: body,
} else { accept: HttpClient.ACCEPT.JSON,
throw new TypeError('Unexpected Content-Type. Expected Content-Type: "application/json". Requested URL:' + url + '"'); }).then(function(response) {
} return response.json();
}).then(function(response) { }).then(function(response) {
processResponse(response[0]); processResponse(response[0]);
}).catch(function(error) { }).catch(function(error) {
var failureMessage = I18n.get('asyncFormFailure'); var failureMessage = I18n.get('asyncFormFailure');
processResponse({ content: failureMessage }); processResponse({ content: failureMessage });
element.classList.remove(ASYNC_FORM_LOADING_CLASS); element.classList.remove(ASYNC_FORM_LOADING_CLASS);
}); });
} }
return init(); return init();

View File

@ -319,15 +319,19 @@
[asyncTableHeader]: asyncTableId [asyncTableHeader]: asyncTableId
}; };
HttpClient.get({ url: url, headers: headers }).then( HttpClient.get({
response => HttpClient.parseHTML(response, element.id) url: url,
).then(function(data) { headers: headers,
accept: HttpClient.ACCEPT.TEXT_HTML,
}).then(function(response) {
return HtmlHelpers.parseResponse(response);
}).then(function(responseElement) {
setLocalStorageParameter('currentTableUrl', url.href); setLocalStorageParameter('currentTableUrl', url.href);
// reset table // reset table
removeListeners(); removeListeners();
element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS); element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS);
// update table with new // update table with new
updateWrapperContents(data); updateWrapperContents(responseElement);
if (callback && typeof callback === 'function') { if (callback && typeof callback === 'function') {
callback(element); callback(element);
@ -340,9 +344,9 @@
}); });
} }
function updateWrapperContents(newHtml) { function updateWrapperContents(newHtmlElement) {
var newPage = document.createElement('div'); var newPage = document.createElement('div');
newPage.appendChild(newHtml); newPage.appendChild(newHtmlElement);
var newWrapperContents = newPage.querySelector('#' + element.id + '__' + element.id); var newWrapperContents = newPage.querySelector('#' + element.id + '__' + element.id);
element.innerHTML = newWrapperContents.innerHTML; element.innerHTML = newWrapperContents.innerHTML;

View File

@ -121,10 +121,15 @@
if (enctype !== 'multipart/form-data') if (enctype !== 'multipart/form-data')
headers['Content-Type'] = enctype; headers['Content-Type'] = enctype;
requestFn({ url: url, headers: headers, body: requestBody }) requestFn({
.then(response => HttpClient.parseHTML(response, element.id)) url: url,
.then(function(response) { headers: headers,
processResponse(response); body: requestBody,
accept: HttpClient.ACCEPT.TEXT_HTML,
}).then(function(response) {
return HtmlHelpers.parseResponse(response);
}).then(function(responseElement) {
processResponse(responseElement);
if (isAddCell) { if (isAddCell) {
reFocusAddCell(); reFocusAddCell();
} }
@ -159,9 +164,9 @@
button.removeEventListener('click', massInputFormSubmitHandler); button.removeEventListener('click', massInputFormSubmitHandler);
} }
function processResponse(response) { function processResponse(responseElement) {
element.innerHTML = ""; element.innerHTML = "";
element.appendChild(response); element.appendChild(responseElement);
reset(); reset();

View File

@ -51,6 +51,7 @@
var modalUrl; var modalUrl;
function _init() { function _init() {
console.log('modalUtil.init', { element });
if (!element) { if (!element) {
throw new Error('Modal utility cannot be setup without an element!'); throw new Error('Modal utility cannot be setup without an element!');
} }
@ -167,15 +168,16 @@
throw new Error('HttpClient not found! Can\'t fetch modal content from ' + url); throw new Error('HttpClient not found! Can\'t fetch modal content from ' + url);
} }
HttpClient.get({ url: url, headers: MODAL_HEADERS }) HttpClient.get({
.then(response => HttpClient.parseHTML(response, element.id)) url: url,
.then(processResponse); headers: MODAL_HEADERS,
accept: HttpClient.ACCEPT.TEXT_HTML,
}).then(function(response) {
return HtmlHelpers.parseResponse(response, element.id);
}).then(processResponse);
} }
function processResponse(responseFrag) { function processResponse(responseElement) {
var responseElement = document.createElement('div');
responseElement.appendChild(responseFrag);
var modalContent = document.createElement('div'); var modalContent = document.createElement('div');
modalContent.classList.add(MODAL_CONTENT_CLASS); modalContent.classList.add(MODAL_CONTENT_CLASS);