Or at least they will once we add the required CSS, but there is at least the JavaScript behaviour in place now.
69 lines
1.7 KiB
JavaScript
69 lines
1.7 KiB
JavaScript
function ready(fn) {
|
|
if (document.readyState !== 'loading') {
|
|
fn();
|
|
} else {
|
|
document.addEventListener('DOMContentLoaded', fn);
|
|
}
|
|
}
|
|
|
|
ready(function () {
|
|
const snackBar = Object.assign(
|
|
document.body.appendChild(document.createElement('section')),
|
|
{
|
|
id: 'snackbar',
|
|
}
|
|
);
|
|
|
|
const errorMessage = snackBar.appendChild(document.createElement('div'));
|
|
errorMessage.setAttribute('role', 'alert');
|
|
|
|
const openClass = 'open';
|
|
const toasts = [];
|
|
let timeoutId = null;
|
|
|
|
function showError(message) {
|
|
toasts.push(message);
|
|
popUp();
|
|
}
|
|
|
|
function popUp() {
|
|
if (toasts.length === 0) {
|
|
return;
|
|
}
|
|
if (errorMessage.classList.contains(openClass)) {
|
|
dismiss();
|
|
return;
|
|
}
|
|
if (errorMessage.innerText !== "") {
|
|
// it will show after remove calls popUp again.
|
|
return;
|
|
}
|
|
errorMessage.innerText = toasts[0];
|
|
errorMessage.classList.add(openClass);
|
|
timeoutId = setTimeout(dismiss, 4000);
|
|
}
|
|
|
|
function dismiss() {
|
|
if (!errorMessage.classList.contains(openClass)) {
|
|
// already dismissed
|
|
return;
|
|
}
|
|
errorMessage.classList.remove(openClass);
|
|
clearTimeout(timeoutId);
|
|
timeoutId = setTimeout(remove, 350);
|
|
}
|
|
|
|
function remove() {
|
|
clearTimeout(timeoutId);
|
|
toasts.splice(0, 1);
|
|
errorMessage.innerText = "";
|
|
popUp();
|
|
}
|
|
|
|
document.body.addEventListener('htmx:error', function (evt) {
|
|
const errorInfo = evt.detail.errorInfo;
|
|
const error = errorInfo.xhr && errorInfo.xhr.responseText || errorInfo.error;
|
|
showError(error);
|
|
});
|
|
})
|