refactor alerts js utility
This commit is contained in:
parent
1c99b36be0
commit
7d7c0d15c9
@ -1068,8 +1068,8 @@ siteLayout' headingOverride widget = do
|
||||
addScript $ StaticR js_services_utilRegistry_js
|
||||
addScript $ StaticR js_services_httpClient_js
|
||||
addScript $ StaticR js_services_i18n_js
|
||||
-- addScript $ StaticR js_utils_alerts_js
|
||||
-- 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
|
||||
|
||||
@ -1,23 +1,3 @@
|
||||
/* ALERTS */
|
||||
/**
|
||||
.alert
|
||||
Regular Info Alert
|
||||
Disappears automatically after 30 seconds
|
||||
Disappears after x seconds if explicitly specified via data-decay='x'
|
||||
Can be told not to disappear with data-decay='0'
|
||||
|
||||
.alert-success
|
||||
Disappears automatically after 30 seconds
|
||||
|
||||
.alert-warning
|
||||
Does not disappear
|
||||
Orange regardless of user's selected theme
|
||||
|
||||
.alert-error
|
||||
Does not disappear
|
||||
Red regardless of user's selected theme
|
||||
|
||||
*/
|
||||
.alerts {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
|
||||
@ -1,68 +1,126 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.utils = window.utils || {};
|
||||
/**
|
||||
*
|
||||
* Alerts Utility
|
||||
* makes alerts interactive
|
||||
*
|
||||
* Attribute: uw-alerts
|
||||
*
|
||||
* Types of alerts:
|
||||
* [default]
|
||||
* Regular Info Alert
|
||||
* Disappears automatically after 30 seconds
|
||||
* Disappears after x seconds if explicitly specified via data-decay='x'
|
||||
* Can be told not to disappear with data-decay='0'
|
||||
*
|
||||
* [success]
|
||||
* Currently no special visual appearance
|
||||
* Disappears automatically after 30 seconds
|
||||
*
|
||||
* [warning]
|
||||
* Will be coloured warning-orange regardless of user's selected theme
|
||||
* Does not disappear
|
||||
*
|
||||
* [error]
|
||||
* Will be coloured error-red regardless of user's selected theme
|
||||
* Does not disappear
|
||||
*
|
||||
* Example usage:
|
||||
* <div .alerts uw-alerts>
|
||||
* <div .alerts__toggler>
|
||||
* <div .alert.alert-info>
|
||||
* <div .alert__closer>
|
||||
* <div .alert__icon>
|
||||
* <div .alert__content>
|
||||
* This is some information
|
||||
*
|
||||
*/
|
||||
|
||||
var ALERTS_CLASS = 'alerts';
|
||||
var ALERTS_UTIL_NAME = 'alerts';
|
||||
var ALERTS_UTIL_SELECTOR = '[uw-alerts]';
|
||||
|
||||
var ALERTS_INITIALIZED_CLASS = 'alerts--initialized';
|
||||
var ALERTS_TOGGLER_CLASS = 'alerts__toggler';
|
||||
var ALERTS_TOGGLER_VISIBLE_CLASS = 'alerts__toggler--visible';
|
||||
var ALERTS_TOGGLER_APPEAR_DELAY = 120;
|
||||
|
||||
var ALERT_CLASS = 'alert';
|
||||
var ALERT_INITIALIZED_CLASS = 'alert--initialized';
|
||||
var ALERT_CLOSER_CLASS = 'alert__closer';
|
||||
var ALERT_INVISIBLE_CLASS = 'alert--invisible';
|
||||
var ALERT_AUTO_HIDE_DELAY = 10;
|
||||
var ALERT_AUTOCLOSING_MATCHER = '.alert-info, .alert-success';
|
||||
|
||||
var JS_INITIALIZED_CLASS = 'js-initialized';
|
||||
|
||||
window.utils.alerts = function(alertsEl) {
|
||||
|
||||
if (alertsEl.classList.contains(JS_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!alertsEl || !alertsEl.classList.contains(ALERTS_CLASS)) {
|
||||
throw new Error('utils.alerts has to be called with alerts element');
|
||||
}
|
||||
|
||||
var alertsUtil = function(element) {
|
||||
var togglerCheckRequested = false;
|
||||
var togglerElement;
|
||||
var alertElements;
|
||||
|
||||
var togglerEl = alertsEl.querySelector('.' + ALERTS_TOGGLER_CLASS);
|
||||
function init() {
|
||||
if (!element) {
|
||||
throw new Error('Alerts util has to be called with an element!');
|
||||
}
|
||||
|
||||
var alertElements = Array.from(alertsEl.querySelectorAll('.' + ALERT_CLASS))
|
||||
.filter(function(alert) {
|
||||
return !alert.classList.contains(JS_INITIALIZED_CLASS);
|
||||
if (element.classList.contains(ALERTS_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
togglerElement = element.querySelector('.' + ALERTS_TOGGLER_CLASS);
|
||||
alertElements = gatherAlertElements();
|
||||
|
||||
initToggler();
|
||||
initAlerts();
|
||||
|
||||
// mark initialized
|
||||
element.classList.add(ALERTS_INITIALIZED_CLASS);
|
||||
|
||||
return {
|
||||
name: ALERTS_UTIL_NAME,
|
||||
element: element,
|
||||
destroy: function() {},
|
||||
};
|
||||
}
|
||||
|
||||
function gatherAlertElements() {
|
||||
return Array.from(element.querySelectorAll('.' + ALERT_CLASS)).filter(function(alert) {
|
||||
return !alert.classList.contains(ALERT_INITIALIZED_CLASS);
|
||||
});
|
||||
}
|
||||
|
||||
function initToggler() {
|
||||
togglerEl.addEventListener('click', function() {
|
||||
togglerElement.addEventListener('click', function() {
|
||||
alertElements.forEach(function(alertEl) {
|
||||
toggleAlert(alertEl, true);
|
||||
});
|
||||
togglerEl.classList.remove(ALERTS_TOGGLER_VISIBLE_CLASS);
|
||||
togglerElement.classList.remove(ALERTS_TOGGLER_VISIBLE_CLASS);
|
||||
});
|
||||
alertsEl.classList.add(JS_INITIALIZED_CLASS);
|
||||
element.classList.add(ALERTS_INITIALIZED_CLASS);
|
||||
}
|
||||
|
||||
function initAlert(alertEl) {
|
||||
function initAlerts() {
|
||||
alertElements.forEach(initAlert);
|
||||
}
|
||||
|
||||
function initAlert(alertElement) {
|
||||
var autoHideDelay = ALERT_AUTO_HIDE_DELAY;
|
||||
if (alertEl.dataset.decay) {
|
||||
autoHideDelay = parseInt(alertEl.dataset.decay, 10);
|
||||
if (alertElement.dataset.decay) {
|
||||
autoHideDelay = parseInt(alertElement.dataset.decay, 10);
|
||||
}
|
||||
|
||||
var closeEl = alertEl.querySelector('.' + ALERT_CLOSER_CLASS);
|
||||
var closeEl = alertElement.querySelector('.' + ALERT_CLOSER_CLASS);
|
||||
closeEl.addEventListener('click', function() {
|
||||
toggleAlert(alertEl);
|
||||
toggleAlert(alertElement);
|
||||
});
|
||||
|
||||
if (autoHideDelay > 0 && alertEl.matches(ALERT_AUTOCLOSING_MATCHER)) {
|
||||
if (autoHideDelay > 0 && alertElement.matches(ALERT_AUTOCLOSING_MATCHER)) {
|
||||
window.setTimeout(function() {
|
||||
toggleAlert(alertEl);
|
||||
toggleAlert(alertElement);
|
||||
}, autoHideDelay * 1000);
|
||||
}
|
||||
|
||||
alertEl.classList.add(JS_INITIALIZED_CLASS);
|
||||
alertElement.classList.add(ALERTS_INITIALIZED_CLASS);
|
||||
}
|
||||
|
||||
function toggleAlert(alertEl, visible) {
|
||||
@ -80,17 +138,19 @@
|
||||
}, true);
|
||||
|
||||
window.setTimeout(function() {
|
||||
togglerEl.classList.toggle(ALERTS_TOGGLER_VISIBLE_CLASS, alertsHidden);
|
||||
togglerElement.classList.toggle(ALERTS_TOGGLER_VISIBLE_CLASS, alertsHidden);
|
||||
togglerCheckRequested = false;
|
||||
}, ALERTS_TOGGLER_APPEAR_DELAY);
|
||||
}
|
||||
|
||||
initToggler();
|
||||
alertElements.forEach(initAlert);
|
||||
|
||||
return {
|
||||
scope: alertsEl,
|
||||
destroy: function() {},
|
||||
};
|
||||
return init();
|
||||
};
|
||||
|
||||
if (UtilRegistry) {
|
||||
UtilRegistry.register({
|
||||
name: ALERTS_UTIL_NAME,
|
||||
selector: ALERTS_UTIL_SELECTOR,
|
||||
setup: alertsUtil,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div #alerts-1 .alerts> <!-- make wIdent work here instead of '#alerts-1' -->
|
||||
<div #alerts-1 .alerts uw-alerts>
|
||||
<div .alerts__toggler>
|
||||
$forall (status, msg) <- mmsgs
|
||||
$with status2 <- bool status "info" (status == "")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user