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
-- JavaScript services
addScript $ StaticR js_services_utilRegistry_js
addScript $ StaticR js_services_htmlHelpers_js
addScript $ StaticR js_services_httpClient_js
addScript $ StaticR js_services_i18n_js
-- 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(
function(response) {
_responseInterceptors.forEach(function(interceptor) { interceptor(response); });
_responseInterceptors.forEach(function(interceptor) {
interceptor(response, options);
});
return Promise.resolve(response);
},
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 {
get: function(args) {
args.method = 'GET';
@ -74,7 +48,25 @@
return _fetch(args);
},
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;
}
HttpClient.post({ url: url, headers: headers, body: 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 = I18n.get('asyncFormFailure');
processResponse({ content: failureMessage });
HttpClient.post({
url: url,
headers: headers,
body: body,
accept: HttpClient.ACCEPT.JSON,
}).then(function(response) {
return response.json();
}).then(function(response) {
processResponse(response[0]);
}).catch(function(error) {
var failureMessage = I18n.get('asyncFormFailure');
processResponse({ content: failureMessage });
element.classList.remove(ASYNC_FORM_LOADING_CLASS);
});
element.classList.remove(ASYNC_FORM_LOADING_CLASS);
});
}
return init();

View File

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

View File

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

View File

@ -51,6 +51,7 @@
var modalUrl;
function _init() {
console.log('modalUtil.init', { element });
if (!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);
}
HttpClient.get({ url: url, headers: MODAL_HEADERS })
.then(response => HttpClient.parseHTML(response, element.id))
.then(processResponse);
HttpClient.get({
url: url,
headers: MODAL_HEADERS,
accept: HttpClient.ACCEPT.TEXT_HTML,
}).then(function(response) {
return HtmlHelpers.parseResponse(response, element.id);
}).then(processResponse);
}
function processResponse(responseFrag) {
var responseElement = document.createElement('div');
responseElement.appendChild(responseFrag);
function processResponse(responseElement) {
var modalContent = document.createElement('div');
modalContent.classList.add(MODAL_CONTENT_CLASS);